<?php

namespace Home\Controller;

/**
 * 订单操作ajax接口
 * @modify trainyao 2016-01-05 创建
 */
class OrderController extends ParentController {

    protected function _initialize() {
        parent::_initialize();
        $this->validateUtil = new \Org\Util\Validate();
        $hotel = I('request.hotel');
        //检查操作权限
        if (!in_array(ACTION_NAME,  array('getShareHistory', 'getOrderUserInfo', 'sendMobile', 'verifyWithMobile', 'orderRoomCheck'))) {
            $adminAuthorityLogic = A('Common/AdminAuthority', 'Logic');
            $adminAuthorityLogic->check($hotel);
        }
        //检查客栈是否已过期
        $hotelLogic = A('Common/Hotel', 'Logic');
        $result = $hotelLogic->checkHotelActive($hotel);
        if ($result == false) {
            returnJson(403, 408);
            return;
        }
        $result = $hotelLogic->checkHotelStatus($hotel);
        if ($result == false) {
            returnJson(403, 401);
            return;
        }
    }

    /**
     * 获取所有子订单
     * @modify trainyao 2016-01-11    创建
     */
    public function getOrderList() {
        $param = I('post.');

        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'start' => 'notnull,notempty,isDate',
            'end' => 'notnull,notempty,isDate',
        );
        $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);

        $hotelId = $param['hotel'];
        $startDate = $param['start'];
        $endDate = $param['end'];

        $orderLogic = A('Common/Order', 'Logic');
        try {
            $orderInfo = $orderLogic->getSubOrder($hotelId, null, 'within', $startDate, $endDate, null, null, null, null, null, null, true);
            $orderInfo = $orderLogic->filteFrontActiveOrder($orderInfo['subOrder'], $startDate, $endDate);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }

        // 删除已删除房间的订单
        foreach ($orderInfo as $index => $subOrder) {
            if ($subOrder['roomInfoDelete'] == IS_DELETE) {
                unset($orderInfo[$index]);
                continue;
            }
        }
        unset($subOrder);
        // 查找是否有订单申请退款
        $refundingSubOrderIds = array();
        if (!empty($orderInfo)) {
            $orderRoomIds = array_column($orderInfo, 'id');
            $orderRefundModel = D('OrderRefund');
            $orderRefundInfo = $orderRefundModel->getInfoByOrder($orderRoomIds);

            foreach ($orderRefundInfo as $index => $orderRefundInfoItem) {
                if ($orderRefundInfoItem['status'] != ORDER_REFUND_APPLY) {
                    unset($orderRefundInfo[$index]);
                }
            }
            unset($orderRefundInfoItem);
            $refundingSubOrderIds = array_column($orderRefundInfo, 'orderroom_id');
        }
        $orderRecordModel = D('OrderRecord');
        // 处理数据
        foreach ($orderInfo as $index => &$subOrder) {

            // 计算已退金额 已退押金
            $orderRecordInfos = $orderRecordModel->getInfoByOrder($subOrder['orderinfo_id']);
            $orderRecordIds = array_column($orderRecordInfos, 'id');
            $payHistoryInfo = $orderLogic->getPayHistoryData($hotelId, $orderRecordIds, true);
            $subOrder['refundPrice'] = '';
            $subOrder['refundDeposit'] = '';
            // 计算其他消费 已收金额
            $subOrder['otherReceivePrice'] = 0;
            $subOrder['otherUncollectePrice'] = 0;
            // 0:收款 1：押金 2：退款 3：退押金
            if (!empty($payHistoryInfo)) {
                foreach ($payHistoryInfo as $key => $payHistoryItem) {
                    switch ($payHistoryItem['type']) {
                        case 2:
                            $subOrder['refundPrice'] += $payHistoryItem['pay'];
                            break;
                        case 3:
                            $subOrder['refundDeposit'] += $payHistoryItem['pay'];
                            break;
                        default:
                            // 他消费已收金额
                            if ($payHistoryItem['hotelpay_id'] != 0 && !in_array($payHistoryItem['type'], [0,1,2,3])) {
                                $subOrder['otherReceivePrice'] += $payHistoryItem['pay'];
                            }
                            // 他消费待收金额
                            if ($payHistoryItem['hotelpay_id'] == 0) {
                                $subOrder['otherUncollectePrice'] += $payHistoryItem['pay'];
                            }
                        break;
                    }
                }
                unset($payHistoryItem);
            }
            if($subOrder['hour'] > 0 && $subOrder['status'] == ORDER_CANCELED) {
                unset($orderInfo[$index]);
                continue;
            }
            $subOrder['starttime'] = $subOrder['startdate'];
            $subOrder['endtime'] = $subOrder['enddate'];
            $subOrder['room'] = $subOrder['roominfo_id'];
            unset($subOrder['roominfo_id']);
            unset($subOrder['createtime']);
            unset($subOrder['creator']);
            $subOrder['status'] = $orderLogic->statusMap[LANG_SET][$subOrder['status']];
            $subOrder['start'] = date('Y-m-d', strtotime($subOrder['startdate']));
            unset($subOrder['startdate']);
            $subOrder['end'] = substr($subOrder['checkoutdate'],0,10);
            unset($subOrder['checkoutdate']);
            $subOrder['enddate'] = substr($subOrder['enddate'],0,10);
            $subOrder['pay'] = $subOrder['payment'];
            unset($subOrder['payment']);
            $subOrder['roomtype'] = $subOrder['roomtype_name'];
            unset($subOrder['roomtype_name']);
            $subOrder['roomname'] = $subOrder['roominfo_name'];
            unset($subOrder['roominfo_name']);
            $subOrder['night'] = $subOrder['realnight'];
            unset($subOrder['realnight']);
            $subOrder['name'] = $subOrder['order']['name'];
            $subOrder['areaCode'] = $subOrder['areacode'];
            unset($subOrder['areacode']);
            $subOrder['mobile'] = $subOrder['order']['mobile'];
            $subOrder['identity'] = $subOrder['order']['identity'];
            $subOrder['deposit'] = $subOrder['order']['deposit'];
            $subOrder['receipt'] = $subOrder['order']['receipt'];
            //$subOrder['price'] = $subOrder['order']['payment'];
            $subOrder['price'] = number_format($subOrder['order']['payment'] + $subOrder['otherUncollectePrice'], '2', '.', '');
            $subOrder['remark'] = $subOrder['order']['remark'];
            $subOrder['channelname'] = $subOrder['order']['channelName'];
            $subOrder['order'] = $subOrder['orderinfo_id'];
            unset($subOrder['orderinfo_id']);
            $subOrder['refunding'] = in_array($subOrder['id'], $refundingSubOrderIds) ? ENABLE : DISABLE;
        }
        unset($subOrder);

        $orderInfo = array_values($orderInfo);
        $orderInfo = my_sort($orderInfo, 'ismidnightorder', SORT_DESC, SORT_NUMERIC);

        returnJson(200, 200, $orderInfo);
    }

    /**
     * 获取筛选订单列表
     * @modify trainyao 2016-08-19    创建
     */
    public function subOrder() {
        $param = I('request.');
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'room' => 'notnull,notempty,id',
            'start' => 'notnull,notempty,isDate',
            'end' => 'notnull,notempty,isDate',
            'type' => 'notempty,natureNumber'
        );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (!$validatePass) {
            return;
        }
        $type = isset($param['type']) ? $param['type'] : 0;
        $startDate = $param['start'];
        $endDate = $param['end'];
        $dateStatus = isset($param['datestatus']) ? $param['datestatus'] : null;

        $startTime = strtotime($startDate);
        // 最多只能查询30天
        if (getTimeDiff($startTime, strtotime($endDate), 'day') >= 30) {
            $endDate = date('Y-m-d', strtotime('+30 days', $startTime));
        }

        // 如果时间状态传入格式不对,使其筛选条件失效
        if (!in_array($dateStatus, array('order', 'checkin', 'checkout'))) {
            $dateStatus = 'order';
        }

        $hotelId = $param['hotel'];
        $roomId = empty($param['room']) ? null : $param['room'];
        $orderLogic = A('Common/Order', 'Logic');
        try {
            $orderInfo = $orderLogic->getSubOrder($hotelId, null, $dateStatus, $startDate, $endDate, $roomId, null, null, null, null, null, true);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }
        // 处理数据
        foreach ($orderInfo['subOrder'] as $key => &$orderInfoItem) {
            if ($type == 1 && $orderInfoItem['hour'] > 0 && $orderInfoItem['month'] > 0) {
                unset($orderInfo['subOrder'][$key]);
                continue;
            } elseif ($type == 2 && $orderInfoItem['night'] > 0) {
                unset($orderInfo['subOrder'][$key]);
                continue;
            } elseif ($type == 3 && $orderInfoItem['month'] == 0) {
                unset($orderInfo['subOrder'][$key]);
                continue;
            }
            $orderInfoItem = array(
                'id' => $orderInfoItem['id'],
                'createTime' => $orderInfoItem['createtime'],
                'startDate' => substr($orderInfoItem['startdate'], 0, 10),
                'endDate' => substr($orderInfoItem['checkoutdate'], 0, 10),
                'roomType' => $orderInfoItem['roomtype_name'],
                'room' => $orderInfoItem['roominfo_name'],
                'price' => $orderInfoItem['payment'],
                'status' => $orderInfoItem['status'],
                'statusName' => $orderLogic->statusMap[LANG_SET][$orderInfoItem['status']],
                'name' => implode(',', array_column($orderInfoItem['user'], 'name')),
                'mobile' => array_diff(array_column($orderInfoItem['user'], 'mobile'), array('')),
                'identity' => array_diff(array_column($orderInfoItem['user'], 'identity'), array('')),
                'channelName' => $orderInfoItem['order']['channelName'],
            );
            $orderInfoItem['mobile'] = implode(',', $orderInfoItem['mobile']);
            $orderInfoItem['identity'] = implode(',', $orderInfoItem['identity']);
        }
        unset($orderInfoItem);
        
        returnJson(200, 200, array_values($orderInfo['subOrder']));
    }

    /**
     * 获取单个订单信息
     * @modify trainyao 2016-01-05    创建
     * @modify paddy 2017-01-22    将原来的rooms拆分为rooms_qr和rooms_rf，仍旧保留原来的rooms，防止其他地方调用出错
     */
    public function getOrder() {
        $param = I('post.');
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'order' => 'notnull,notempty,id',
        );
        $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);

        $hotelId = $param['hotel'];
        $orderInfoId = explode(',', $param['order']);
        $orderLogic = A('Common/Order', 'Logic');
        try {
            $orderInfo = $orderLogic->getOrderInfo($hotelId, $orderInfoId);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }

        $hotelLogic = A('Common/Hotel', 'Logic');
        $hotelBookDetail = $hotelLogic->getHotelBookingDetail($hotelId);
        $hotelCheckoutTime = isset($hotelBookDetail['checkouttime']) ? $hotelBookDetail['checkouttime'] : '12:00';
        $hotelCheckinTime = isset($hotelBookDetail['checkintime']) ? $hotelBookDetail['checkintime'] : '14:00';

        // 查找是否有子订单退款中
        $orderRoomIds = array_column($orderInfo[0]['rooms'], 'id');
        $orderRefundModel = D('OrderRefund');
        $orderRefundInfo = $orderRefundModel->getInfoByOrder($orderRoomIds);
        $orderInfo[0]['refunding'] = (empty($orderRefundInfo) || !in_array(ORDER_REFUND_APPLY, array_column($orderRefundInfo, 'status'))) ? DISABLE : ENABLE;

        // 处理数据
        unset($orderInfo[0]['hotelentity_id']);
        $orderInfo[0]['channelid'] = $orderInfo[0]['hotelchannel_id'];
        unset($orderInfo[0]['hotelchannel_id']);
        unset($orderInfo[0]['userlogin_id']);
        //$orderInfo[0]['pay'] = $orderInfo[0]['payment'];
        // 订单金额加上 其他消费 待收金额
        $orderInfo[0]['pay'] = number_format($orderInfo[0]['payment'] + $orderInfo[0]['otherUncollectePrice'], '2', '.', '');
        unset($orderInfo[0]['payment']);
        $orderInfo[0]['areaCode'] = $orderInfo[0]['areacode'];
        unset($orderInfo[0]['areacode']);
        $orderInfo[0]['receipt'] = $orderInfo[0]['receipt'];

        // 获取是否还可重复发送短信房卡
        $orderInfoId = $orderInfo[0]['id'];
        if (empty($this->redisUtil)) {
            $this->redisUtil = new \Org\Util\RedisHelper(null, null, 'meizhu');
        }
        $this->redisUtil->db(C('REDIS_HOME_DB'))->table('orderRoomSendMobile');
        $sendTimesItem = $this->redisUtil->hMGet($orderInfoId);
        // 这个参数只是查看次数是否被允许，前端仍需根据每个子订单是否为锁掌柜房间，是否为入住状态，且拥有手机号，结束时间未过期判断能否显示重新发送
        $orderInfo[0]['canSendAgain'] = 1;
        if (!empty($sendTimesItem)) {
            $sendTimes = $sendTimesItem['times'];
            if ($sendTimes >= 3) {
                $orderInfo[0]['canSendAgain'] = 0;
            }
        }

        // 子订单
        $orderInfo[0]['rooms_qr'] = array();
        $orderInfo[0]['rooms_rf'] = array();
        if (!empty($orderInfo[0]['rooms'])) {
            foreach ($orderInfo[0]['rooms'] as &$room) {
                // 订单打印的入住时间与退房时间 $checkintime $checkouttime
                $checkintime = $room['checkindate'] == '0000-00-00 00:00:00' ? date('m/d', strtotime($room['startdate'])) . ' ' . $hotelCheckinTime : date('m/d H:i', strtotime($room['checkindate']));
                $checkouttime = $room['printcheckoutdate'] == '0000-00-00 00:00:00' ? date('m/d', strtotime($room['checkoutdate'])) . ' ' . $hotelCheckoutTime : date('m/d H:i', strtotime($room['printcheckoutdate']));

                unset($room['createtime']);
                unset($room['creator']);
                unset($room['name']);
                unset($room['mobile']);
                unset($room['areacode']);
                unset($room['identity']);
                unset($room['orderinfo_id']);
                $room['roomid'] = $room['roominfo_id'];
                unset($room['roominfo_id']);
                $room['status'] = $orderLogic->statusMap[LANG_SET][$room['status']];
                $room['pay'] = $room['payment'];
                unset($room['payment']);
                $room['starttime'] = $room['startdate'];
                $room['startdate'] = date('Y-m-d', strtotime($room['startdate']));
                $room['enddate'] = date('Y-m-d', strtotime($room['enddate']));
                $room['checkintime'] = $checkintime;
                $room['checkouttime'] = $checkouttime;
                $room['checkoutdate'] = date('Y-m-d', strtotime($room['checkoutdate']));
                $room['printcheckouttime'] = $room['printcheckoutdate'] != '0000-00-00 00:00:00' ? $room['printcheckoutdate'] : $room['user'][0]['enddate'];
                $room['type'] = $room['roomtype_name'];
                $room['room'] = $room['roominfo_name'];
                $room['ismidnightorder'] = $room['ismidnightorder'] ? true : false;
                unset($room['roomtype_name']);
                unset($room['roominfo_name']);
                $room['roomFrom'] = $room['roominfo_from'];
                unset($room['roominfo_from']);
                foreach ($room['user'] as &$user) {
                    $user = array(
                        'userRoom' => $user['userroom_id'],
                        'orderUser' => $user['orderuser_id'],
                        'name' => $user['name'],
                        'areaCode' => $user['areacode'],
                        'mobile' => $user['mobile'],
                        'identity' => $user['identity'],
                        'printCount' => $user['printcount'],
                        'rfCount' => $user['rfcount'],
                        'isdelete' => $user['isdelete'],
                    );
                }
                unset($user);
                if ($room['roomFrom'] == 1 || $room['roomFrom'] == 3) {
                    $orderInfo[0]['rooms_qr'][] = $room;
                }
                if ($room['roomFrom'] == 2 || $room['roomFrom'] == 3|| $room['roomFrom'] == 5) {
                    $orderInfo[0]['rooms_rf'][] = $room;
                }
            }
            unset($room);
        }

        returnJson(200, 200, $orderInfo[0]);
    }

    /**
     * 获取订单修改历史
     * @modify trainyao 2016-01-05    创建
     */
    public function getHistory() {
        $param = I('post.');

        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'order' => 'notnull,notempty,id'
        );
        $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);

        $hotelId = $param['hotel'];
        $orderId = $param['order'];
        $orderLogic = A('Common/Order', 'Logic');
        try {
            $historyInfo = $orderLogic->getHistory($hotelId, $orderId);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }

        // 数据处理
        unset($historyInfo['id']);
        unset($historyInfo['hotelentity_id']);
        unset($historyInfo['hotelchannel_id']);
        $historyInfo['pay'] = $historyInfo['payment'];
        unset($historyInfo['payment']);
        // 子订单
        if (!empty($historyInfo['rooms'])) {
            foreach ($historyInfo['rooms'] as &$room) {
                unset($room['createtime']);
                unset($room['id']);
                unset($room['orderinfo_id']);
                unset($room['roominfo_id']);
                $room['status'] = $orderLogic->statusMap[LANG_SET][$room['status']];
                $room['pay'] = $room['payment'];
                unset($room['payment']);
                $room['startdate'] = date('Y-m-d', strtotime($room['startdate']));
                $room['enddate'] = date('Y-m-d', strtotime($room['enddate']));
                $room['type'] = $room['roomtype_name'];
                $room['room'] = $room['roominfo_name'];
                unset($room['roomtype_name']);
                unset($room['roominfo_name']);
            }
            unset($room);
        }
        // 用户
        if (!empty($historyInfo['users'])) {
            foreach ($historyInfo['users'] as &$user) {
                unset($user['id']);
                unset($user['isdelete']);
                unset($user['orderinfo_id']);
                unset($user['userlogin_id']);
            }
            unset($user);
        }

        returnJson(200, 200, $historyInfo);
    }

    /**
     * 获取订单支付历史
     * @modify trainyao 2016-01-14    创建
     */
    public function getPayHistory() {
        $param = I('post.');

        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'order' => 'notnull,notempty,id'
        );
        $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);

        $hotelId = $param['hotel'];
        $orderId = $param['order'];
        $orderLogic = A('Common/Order', 'Logic');
        try {
            $historyInfo = $orderLogic->getPayHistory($hotelId, $orderId);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }

        // 处理数据
        foreach ($historyInfo as &$history) {
            unset($history['id']);
            unset($history['orderrecord_id']);
            unset($history['createtime']);
            unset($history['creator']);
            unset($history['hotelentity_id']);
            unset($history['orderinfo_id']);
            unset($history['hotelpay_id']);
        }
        unset($history);

        returnJson(200, 200, $historyInfo);
    }

    /**
     * @description 录入订单||状态为0
     * @modify songanwei 2016-01-04
     */
    public function add() {
        $this->addOrder(1);
    }

    /**
     * @description 直接入住
     * @modify songanwei 2016-01-15
     */
    public function orderCheckIn() {
        $this->addOrder(2);
    }

    /**
     * 入住订单重发短信接口
     * @modify AmosZhong 2016-08-08  创建
     */
    public function resendCheckInOrderSMS() {
        $param = I('post.');

        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'order' => 'notnull,notempty,id',
            'orderUser' => 'notnull,notempty,id',
        );
        $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);


        $hotelId = $param['hotel'];
        $orderRoomId = $param['order'];
        $orderUserId = $param['orderUser'];
        $orderLogic = A('Common/Order', 'Logic');
        
        try {
            $resendTimes = $orderLogic->resendCheckInOrderSMS($hotelId, $orderRoomId, $orderUserId);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }

        $canSendAgain = $resendTimes >= 3 ? 0 : 1;
        returnJson(200, 200, $canSendAgain);
    }

    /**
     * @description 补录订单||状态为已退房
     * @modify songanwei 2016-01-15
     */
    public function orderOld() {
        $this->addOrder(3);
    }

    /**
     * @description 修改订单|| 参数
     * @modify songanwei 2016-01-05
     */
    public function edit() {
        $params = I('post.');
        $hotelChannelId = $params['channel']; //来源渠道
        $hotelId = $params['hotel']; //客栈ID
        $orderId = $params['order']; //订单ID
        $remark = $params['remark']; //备注
        $orderRecord = $params['detail'];
        $receives = $params['receive'];
        $vip = $params['vip'];
        $orderPayRecord = $params['orderPayRecord'];
        $couponGetNo = isset($params['couponGetNo']) && !empty($params['couponGetNo']) ? $params['couponGetNo'] : null; //优惠券用户领取号
        $userId = getUserId();
        //检查参数
        $orderRecordValidateRule = array(
            'orderRoomId' => 'id',
            'roomId' => 'notnull,notempty,id',
            'orderDate' => 'notnull,notempty',
            'nights' => 'notnull,bookNight',
            'payment' => 'notnull,decimal8_2',
            'users' => 'notnull,notempty',
            'hour' => 'bookHour',
            'month' => 'bookMonth',
        );
        $orderUserValidateRule = array(
            'orderUser' => 'id',
            'name' => 'notnull,notempty,nameLength20',
            'identity' => 'IDCard',
        );
        $orderPayRecordValidateRule = array(
            'id' => 'notnull,notempty,id',
            'hotelPayId' => 'notnull,notempty,id',
            'type' => 'notnull,notempty,id',
            'pay' => 'notnull,notempty,decimal8_2',
            'transCurrencyId' => 'notnull,notempty,id',
        );
        $orderUserModel = D('OrderUser');
        $orderUserInfo = $orderUserModel->getInfoByOrder($params['order']);
        $orderUserInfo = getArrayValueAsIndex($orderUserInfo, 'id');
        foreach ($orderRecord as &$subOrderItem) {
            $validatePass = $this->ajaxValidateReturn($this->validateUtil, $subOrderItem, $orderRecordValidateRule);
            if (!$validatePass) {
                return;
            }

            foreach ($subOrderItem['users'] as &$orderUserItem) {
                if (empty($orderUserItem['identity'])) {
                    unset($orderUserValidateRule['identity']);
                }

                $validatePass = $this->ajaxValidateReturn($this->validateUtil, $orderUserItem, $orderUserValidateRule);
                if (!$validatePass) {
                    return;
                }

                $orderUserItem['orderUser'] = (!isset($orderUserItem['orderUser']) || empty($orderUserItem['orderUser'])) ? 0 : $orderUserItem['orderUser'];
                $oldMobile = '';
                $oldidentity = '';
                $oldidsex = '';
                $oldidnation = '';
                $oldidaddress = '';
                if(!empty($orderUserItem['orderUser'])&&isset($orderUserInfo[$orderUserItem['orderUser']])){
                    $oldMobile = $orderUserInfo[$orderUserItem['orderUser']]['mobile'];
                    $oldidentity = $orderUserInfo[$orderUserItem['orderUser']]['identity'];
                    $oldidsex = $orderUserInfo[$orderUserItem['orderUser']]['idsex'];
                    $oldidnation = $orderUserInfo[$orderUserItem['orderUser']]['idnation'];
                    $oldidaddress = $orderUserInfo[$orderUserItem['orderUser']]['idaddress'];
                }
                $orderUserItem['mobile'] = isset($orderUserItem['mobile']) ? $orderUserItem['mobile'] : $oldMobile;
                $orderUserItem['identity'] = isset($orderUserItem['identity']) ? $orderUserItem['identity'] : $oldidentity;
                $orderUserItem['idsex'] = isset($orderUserItem['idsex']) ? $orderUserItem['idsex'] : $oldidsex;
                $orderUserItem['idnation'] = isset($orderUserItem['idnation']) ? $orderUserItem['idnation'] : $oldidnation;
                $orderUserItem['idaddress'] = isset($orderUserItem['idaddress']) ? $orderUserItem['idaddress'] : $oldidaddress;

                // 全局校验号码
                if (isset($orderUserItem['mobile']) && !empty($orderUserItem['mobile'])) {
                    $orderUserItem['areacode'] = isset($orderUserItem['areaCode']) && !empty($orderUserItem['areaCode']) ? $orderUserItem['areaCode'] : '86';
                    if (isset($orderUserItem['areaCode'])) unset($orderUserItem['areaCode']);
                    $validatePass = $this->ajaxValidateReturn($this->validateUtil, $orderUserItem['mobile'], 'globalMobile',
                        array('globalMobile' => array('function', 'checkGlobalMobile,' . $orderUserItem['areacode'], '403,130,error'),
                    ));
                    if (!$validatePass) {
                        return;
                    }
                }
            }
            if (isset($subOrderItem['month'])) {
                $subOrderItem['nights'] = getNight($subOrderItem['orderDate'], date('Y-m-d',strtotime('+' . $subOrderItem['month'] . 'months', strtotime($subOrderItem['orderDate']))));
            }
            unset($orderUserItem);
            $subOrderItem['orderRoomId'] = (!isset($subOrderItem['orderRoomId']) || empty($subOrderItem['orderRoomId'])) ? 0 : $subOrderItem['orderRoomId'];
        }
        unset($subOrderItem);
        $this->ajaxValidateReturn($this->validateUtil, $remark, "notnull,nameLength255");

        if (isset($orderPayRecord) && !is_null($orderPayRecord)) {
            foreach ($orderPayRecord as $key => $orderPayRecordItem) {
                $validatePass = $this->ajaxValidateReturn($this->validateUtil, $orderPayRecordItem, $orderPayRecordValidateRule);
                if (!$validatePass) {
                    return;
                }
            }
            unset($orderPayRecordItem);
        }

        // 会员卡信息
        $vipCard = array();
        if (isset($params['vipCard'])) {
            $vipCard = $params['vipCard'];
            $this->ajaxValidateReturn($this->validateUtil, $vipCard['cardMobile'], 'globalMobile', array('globalMobile' => array('function', 'checkGlobalMobile,' . $vipCard['cardAreaCode'], '403,130,error'),
                    ));
        }

        // 取出默认货币
        $currencyLogic = A('Common/Currency', 'Logic');
        $hotelDefaultCurrency = $currencyLogic->takeHotelCurrency($hotelId, true);
        $currencyId = !empty($hotelDefaultCurrency) ? $hotelDefaultCurrency[0]['currencyId'] : 8 ; // 8 = 人民币

        $deposit = 0.00; //押金
        $receipt = 0.00; //已收金额
        //计算总额
        foreach ($receives as $index => &$receive) {
            $isTrans = false;
            if ($receive['transCurrencyId'] != 0 && $currencyId != $receive['transCurrencyId'] && (double) $receive['value'] != 0) {
                $isTrans = true;
            }

            $receive['transBeforeValue'] = $receive['value'];
            if ($receive['category'] == 1) {
                // 价格汇率转换
                if ($isTrans) {
                    $receive['value'] = $currencyLogic->exchangeRates($receive['transCurrencyId'], $currencyId, $receive['value']);
                }

                $deposit+= $receive['value'];
            } else if ($receive['category'] == 0) {
                // 价格汇率转换
                if ($isTrans) {
                    $receive['value'] = $currencyLogic->exchangeRates($receive['transCurrencyId'], $currencyId, $receive['value']);
                }

                $receipt+= $receive['value'];
            } else if ($receive['type'] != 0) {
                // 价格汇率转换
                if ($isTrans) {
                    $receive['value'] = $currencyLogic->exchangeRates($receive['transCurrencyId'], $currencyId, $receive['value']);
                }

                // 其他消费 （不含待收款）
                $receipt+= $receive['value'];
            }  else if ($receive['type'] == 0) {
                // 带收款 价格汇率转换
                if ($isTrans) {
                    $receive['value'] = $currencyLogic->exchangeRates($receive['transCurrencyId'], $currencyId, $receive['value']);
                }
            }

            //过滤数据
            if ((double) $receive['value'] == 0) {
                unset($receives[$index]);
            }
        }

        // 补充默认货币
        if (isset($orderPayRecord) && !is_null($orderPayRecord)) {
            foreach ($orderPayRecord as $key => &$orderPayRecordItem) {
                // 价格汇率转换
                $orderPayRecordItem['currencyId'] = $currencyId;
            }
            unset($orderPayRecordItem);
        }

        $orderLogic = A('Common/Order', 'Logic');
        //判断订单状态
        try {
            $orderLogic->saveInfo($hotelId, $orderId, $hotelChannelId, $deposit, $receipt, $remark, $orderRecord, $receives, 0, null, false, $vip, null, $orderPayRecord, $vipCard, $couponGetNo);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }

        returnJson(200, 200);
    }

    /**
     * 取消订单
     * @modify trainyao 2016-01-06    创建
     */
    public function cancel() {
        $param = I('post.');

        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'order' => 'notnull,notempty,id',
            'suborder' => 'notnull,notempty,id',
            'receipt' => 'notempty,decimal8_2',
            'receiptpay' => 'notempty,id',
            'deposit' => 'notempty,decimal8_2',
            'depositpay' => 'notempty,id',
            'remark' => 'notnull,nameLength255',
            'receiptCurrencyId' => 'notempty,id',
            'depositCurrencyId' => 'notempty,id',
        );
        $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);

        $hotelId = $param['hotel'];
        $orderId = $param['order'];
        $deposit = $param['deposit'];
        $receipt = $param['receipt'];
        $depositPay = $param['depositpay'];
        $receiptPay = $param['receiptpay'];
        $receiptCurrencyId = isset($param['receiptCurrencyId']) ? $param['receiptCurrencyId'] : 0;
        $depositCurrencyId = isset($param['depositCurrencyId']) ? $param['depositCurrencyId'] : 0;
        if ($receipt == 0) {
            $receipt = null;
        }
        if ($deposit >= 0) {
            $deposit = null;
        }

        // 取出默认货币
        $currencyLogic = A('Common/Currency', 'Logic');
        $hotelDefaultCurrency = $currencyLogic->takeHotelCurrency($hotelId, true);
        $currencyId = !empty($hotelDefaultCurrency)  ? $hotelDefaultCurrency[0]['currencyId'] : 8 ; // 8 = 人民币

        // 价格汇率转换
        $receiptBeforeValue = !is_null($receipt) ? $receipt : 0;
        $depositBeforeValue = !is_null($deposit) ? $deposit : 0;
        if (isset($param['receiptCurrencyId']) && !is_null($receipt) && $currencyId != $receiptCurrencyId) {
            $receipt = $currencyLogic->exchangeRates($receiptCurrencyId, $currencyId, $receipt);
        }
        if (isset($param['depositCurrencyId']) && !is_null($deposit) && $currencyId != $depositCurrencyId) {
            $deposit = $currencyLogic->exchangeRates($depositCurrencyId, $currencyId, $deposit);
        }

        $remark = $param['remark'];
        $subOrderIds = array($param['suborder']);
        $orderLogic = A('Common/Order', 'Logic');

        try {
            $orderLogic->cancelOrder($hotelId, $orderId, $subOrderIds, ORDER_CHANGE_WEB, $deposit, $depositPay, $receipt, $receiptPay, $remark, null, false, $receiptBeforeValue, $depositBeforeValue, $receiptCurrencyId, $depositCurrencyId);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }
        returnJson(200, 200, 'success');
    }

    /**
     * 退房ajax接口
     * @modify trainyao 2016-01-06    创建
     */
    public function checkout() {
        $param = I('post.');
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'order' => 'notnull,notempty,id',
            'suborder' => 'notnull,notempty,concatId',
            'receipt' => 'notempty,decimal8_2',
            'receiptpay' => 'notempty,id',
            'deposit' => 'notempty,decimal8_2',
            'depositpay' => 'notempty,id',
            'remark' => 'notnull,nameLength255',
            'receiptCurrencyId' => 'notempty,id',
            'depositCurrencyId' => 'notempty,id',
        );

        $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);

        $hotelId = $param['hotel'];
        $orderId = $param['order'];
        $subOrderIds = explode(',', $param['suborder']);
        $deposit = $param['deposit'];
        $receipt = $param['receipt'];
        $depositPay = $param['depositpay'];
        $receiptPay = $param['receiptpay'];
        $receiptCurrencyId = isset($param['receiptCurrencyId']) ? $param['receiptCurrencyId'] : 0;
        $depositCurrencyId = isset($param['depositCurrencyId']) ? $param['depositCurrencyId'] : 0;
        $remark = $param['remark'];
        if ($receipt == 0) {
            $receipt = null;
        }
        if ($deposit >= 0) {
            $deposit = null;
        }

        // 取出默认货币
        $currencyLogic = A('Common/Currency', 'Logic');
        $hotelDefaultCurrency = $currencyLogic->takeHotelCurrency($hotelId, true);
        $currencyId = !empty($hotelDefaultCurrency) ? $hotelDefaultCurrency[0]['currencyId'] : 8 ; // 8 = 人民币

        // 价格汇率转换
        $receiptBeforeValue = !is_null($receipt) ? $receipt : 0;
        $depositBeforeValue = !is_null($deposit) ? $deposit : 0;
        if (isset($param['receiptCurrencyId']) && !is_null($receipt) && $currencyId != $receiptCurrencyId) {
            $receipt = $currencyLogic->exchangeRates($receiptCurrencyId, $currencyId, $receipt);
        }
        if (isset($param['depositCurrencyId']) && !is_null($deposit) && $currencyId != $depositCurrencyId) {
            $deposit = $currencyLogic->exchangeRates($depositCurrencyId, $currencyId, $deposit);
        }

        $orderLogic = A('Common/Order', 'Logic');
        try {
            $orderLogic->checkOutOrder($hotelId, $orderId, $subOrderIds, ORDER_CHANGE_WEB, $subOrderIds, $receipt, $receiptPay, $deposit, $depositPay, $remark, null, false, $receiptBeforeValue, $depositBeforeValue, $receiptCurrencyId, $depositCurrencyId);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }

        returnJson(200, 200);
        return;
    }

    /**
     * 办理入住ajax接口
     * @modify trainyao 2016-01-07    创建
     */
    public function checkin() {
        $param = I('post.');

        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'order' => 'notnull,notempty,id',
            'data' => 'notnull,notempty',
            // 可空参数
            'receipt' => 'notempty,decimal8_2',
            'receiptpay' => 'notempty,id',
            'deposit' => 'notempty,decimal8_2',
            'depositpay' => 'notempty,id',
            'remark' => 'notnull,nameLength255',
            'receiptCurrencyId' => 'notempty,id',
            'depositCurrencyId' => 'notempty,id',
        );
        $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        $orderRoomData = json_decode(htmlspecialchars_decode($param['data']), true);
        $validateRule = array(
            'value' => 'notnull,notempty,id',
        );
        $orderUserValidateRule = array(
            'orderUser' => 'notnull,notempty,id',
            'name' => 'notnull,notempty,nameLength20',
            'mobile' => 'notempty',
            'identity' => 'notempty,IDCard',
        );
        $orderUserModel = D('OrderUser');
        $orderUserInfo = $orderUserModel->getInfoByOrder($param['order']);
        $orderUserInfo = getArrayValueAsIndex($orderUserInfo, 'id');
        foreach ($orderRoomData as &$orderRoom) {
            $validatePass = $this->ajaxValidateReturn($this->validateUtil, $orderRoom, $validateRule);
            if (!$validatePass) {
                return;
            }

            foreach ($orderRoom['users'] as &$orderUserItem) {
                $validatePass = $this->ajaxValidateReturn($this->validateUtil, $orderUserItem, $orderUserValidateRule);
                if (!$validatePass) {
                    return;
                }
                $oldMobile = '';
                $oldidentity = '';
                $oldidsex = '';
                $oldidnation = '';
                $oldidaddress = '';
                if(!empty($orderUserItem['orderUser'])&&isset($orderUserInfo[$orderUserItem['orderUser']])){
                    $oldMobile = $orderUserInfo[$orderUserItem['orderUser']]['mobile'];
                    $oldidentity = $orderUserInfo[$orderUserItem['orderUser']]['identity'];
                    $oldidsex = $orderUserInfo[$orderUserItem['orderUser']]['idsex'];
                    $oldidnation = $orderUserInfo[$orderUserItem['orderUser']]['idnation'];
                    $oldidaddress = $orderUserInfo[$orderUserItem['orderUser']]['idaddress'];
                }
                $orderUserItem['mobile'] = isset($orderUserItem['mobile']) ? $orderUserItem['mobile'] : $oldMobile;
                $orderUserItem['identity'] = isset($orderUserItem['identity']) ? $orderUserItem['identity'] : $oldidentity;
                $orderUserItem['idsex'] = isset($orderUserItem['identity']) ? $orderUserItem['identity'] : $oldidsex;
                $orderUserItem['idnation'] = isset($orderUserItem['identity']) ? $orderUserItem['identity'] : $oldidnation;
                $orderUserItem['idaddress'] = isset($orderUserItem['identity']) ? $orderUserItem['identity'] : $oldidaddress;
                
                // 全局校验号码
                $orderUserItem['areacode'] = isset($orderUserItem['areaCode']) && !empty($orderUserItem['areaCode']) ? $orderUserItem['areaCode'] : '86';
                if (isset($orderUserItem['areaCode'])) unset($orderUserItem['areaCode']);

                if (!empty($orderUserItem['mobile'])) {
                    $validatePass = $this->ajaxValidateReturn($this->validateUtil, $orderUserItem['mobile'], 'globalMobile',
                        array('globalMobile' => array('function', 'checkGlobalMobile,' . $orderUserItem['areacode'], '403,130,error'),
                    ));
                    if (!$validatePass) {
                        return;
                    }
                }
            }
            unset($orderUserItem);
        }
        unset($orderRoom);

        // 会员卡信息
        $vipCard = array();
        if (isset($param['vipCard'])) {
            $vipCard = $param['vipCard'];
            $this->ajaxValidateReturn($this->validateUtil, $vipCard['cardMobile'], 'globalMobile', array('globalMobile' => array('function', 'checkGlobalMobile,' . $vipCard['cardAreaCode'], '403,130,error'),
                    ));
        }

        $hotelId = $param['hotel'];
        $orderId = $param['order'];
        $subOrderIds = array_column($orderRoomData, 'value');
        $receipt = $param['receipt'];
        $receiptPay = $param['receiptpay'];
        $deposit = $param['deposit'];
        $depositPay = $param['depositpay'];
        $remark = $param['remark'];
        $checkIn = isset($param['checkIn']) ? $param['checkIn'] : 0;
        $receiptCurrencyId = isset($param['receiptCurrencyId']) ? $param['receiptCurrencyId'] : 0;
        $depositCurrencyId = isset($param['depositCurrencyId']) ? $param['depositCurrencyId'] : 0;

        if ($receipt <= 0) {
            $receipt = null;
            $receiptPay = null;
        }
        if ($deposit <= 0) {
            $deposit = null;
            $depositPay = null;
        }

        $orderLogic = A('Common/Order', 'Logic');
        // 判断是否检查当天之前的房间状态 即是否脏房、已预订或已入住 检查并返回数据
        if ($checkIn == 1) {
            // 根据 value 获取房间id
            $id = array();
            foreach ($orderRoomData as $key => $orderItem) {
                 array_push($id, $orderItem['value']);
            }
            unset($orderItem);

            $orderRoomModel = D('OrderRoom');
            $roomInfo = $orderRoomModel -> getInfo($id);

            $roomIds = '';
            foreach ($roomInfo as $key => $roomInfoItem) {
                 $roomIds .= $roomInfoItem['roominfo_id'] . ',';
            }
            unset($roomInfoItem);
            $roomIds = substr($roomIds, 0, -1);

            try {
                //获取该房间当天之前已预订或已入住的房间信息
                $dirtyData = $orderLogic->checkInOrder($hotelId, $orderId, $subOrderIds, ORDER_CHANGE_WEB, $orderRoomData, $receipt, $receiptPay, $deposit, $depositPay, $remark, null, $checkIn, $roomIds);
            } catch (\Exception $e) {
                returnJson($e->getMessage());
                return;
            }

            //返回查询数据信息
            $roomIds = array();
            foreach ($roomInfo as $key => $roomInfoItem) {
                 $ids  = array($key => $roomInfoItem['roominfo_id']);
                 array_push($roomIds, $ids);
            }
            unset($roomInfoItem);

            if (!empty($dirtyData)) {
                // 组装返回数据 返回查询数据信息
                $roomDirty = array();
                foreach ($roomIds as $orderKey => $orderItem) {
                    foreach ($dirtyData as $irtyKey => $dirtyItem) {
                        if ($irtyKey == 'orderRoomInfos') {
                            foreach ($dirtyItem as $listKey => $dirtyItemList) {
                                if ($orderItem[$orderKey] == $dirtyItemList['roomId']) {
                                    $roomDirty['roomStatus'][$dirtyItemList['roomId']] = array(
                                        'rooId' => $dirtyItemList['roomId'],
                                        'roomName' => $dirtyItemList['roomName'],
                                        'status' => $dirtyItemList['status'],
                                    );
                                }
                            }
                            unset($dirtyItemList);
                        }
                    }
                    unset($dirtyItem);
                }
                unset($orderiItem);

                $dirtyData['orderRoomInfos'] =  array_values($roomDirty['roomStatus']);
                if (!empty($vipCard)) {
                    $dirtyData['vipCard'] =  $vipCard;
                }
                returnJson(403, 308, $dirtyData);
            }
        }


        // 取出默认货币
        $currencyLogic = A('Common/Currency', 'Logic');
        $hotelDefaultCurrency = $currencyLogic->takeHotelCurrency($hotelId, true);
        $currencyId = !empty($hotelDefaultCurrency) ? $hotelDefaultCurrency[0]['currencyId'] : 8 ; // 8 = 人民币

        // 价格汇率转换
        $receiptBeforeValue = !is_null($receipt) ? $receipt : 0;
        $depositBeforeValue = !is_null($deposit) ? $deposit : 0;
        if (isset($param['receiptCurrencyId']) && !is_null($receipt) && $currencyId != $receiptCurrencyId) {
            $receipt = $currencyLogic->exchangeRates($receiptCurrencyId, $currencyId, $receipt);
        }
        if (isset($param['depositCurrencyId']) && !is_null($deposit) && $currencyId != $depositCurrencyId) {
            $deposit = $currencyLogic->exchangeRates($depositCurrencyId, $currencyId, $deposit);
        }

        // 检查并添加数据
        try {
            $orderAfterCheckInData = $orderLogic->checkInOrder($hotelId, $orderId, $subOrderIds, ORDER_CHANGE_WEB, $orderRoomData, $receipt, $receiptPay, $deposit, $depositPay, $remark, null, 0, '', '', null, $receiptBeforeValue, $depositBeforeValue, $receiptCurrencyId, $depositCurrencyId);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }

        // 处理数据
        foreach ($orderAfterCheckInData['suborder'] as $orderRoomId => &$orderRoom) {
            $orderRoom['channelname'] = $orderAfterCheckInData['order']['channelName'];
            $orderRoom['deposit'] = $orderAfterCheckInData['order']['deposit'];
            $orderRoom['price'] = $orderAfterCheckInData['order']['payment'];
            $orderRoom['receipt'] = $orderAfterCheckInData['order']['receipt'];
            $orderRoom['name'] = $orderAfterCheckInData['order']['name'];
            $orderRoom['mobile'] = $orderAfterCheckInData['order']['mobile'];
            $orderRoom['identity'] = $orderAfterCheckInData['order']['identity'];
            $orderRoom['remark'] = $orderAfterCheckInData['order']['remark'];

            $orderRoom['status'] = $orderLogic->statusMap[LANG_SET][ORDER_CHECKINED];

            $orderRoom['order'] = $orderRoom['orderinfo_id'];
            unset($orderRoom['orderinfo_id']);
            $orderRoom['room'] = $orderRoom['roominfo_id'];
            unset($orderRoom['roominfo_id']);
            $orderRoom['pay'] = $orderRoom['payment'];
            unset($orderRoom['payment']);
            $orderRoom['start'] = date('Y-m-d', strtotime($orderRoom['startdate']));
            unset($orderRoom['startdate']);
            $orderRoom['end'] = date('Y-m-d', strtotime($orderRoom['enddate']));
            unset($orderRoom['enddate']);
            $orderRoom['roomtype'] = $orderRoom['roomtype_name'];
            unset($orderRoom['roomtype_name']);
            $orderRoom['roomname'] = $orderRoom['roominfo_name'];
            unset($orderRoom['roominfo_name']);

            unset($orderRoom['createtime']);
            unset($orderRoom['user']);
        }
        unset($orderRoom);

        //进入消息队列
        returnJson(200, 200, array_values($orderAfterCheckInData['suborder']));
    }

    /**
     * 根据条件筛选到订单数据到Excel
     * @modify songanwei 2016-01-15
     */
    public function exportList() {
        $param = I('request.');
        $startDate = $param['start'];
        $startDate = empty($startDate) ? date('Y-m-d', strtotime('-3 days')) : $startDate;
        $endDate = $param['end'];
        $endDate = empty($endDate) ? date('Y-m-d', strtotime('+27 days')) : $endDate;
        $dateStatus = $param['datestatus'];
        $type = isset($param['type']) ? $param['type'] : 0;
        $startTime = strtotime($startDate);
        $endTime = strtotime($endDate);
        // 最多只能查询30天
        if (getTimeDiff($startTime, $endTime, 'day') >= 30) {
            $endDate = date('Y-m-d', strtotime('+30 days', $startTime));
        }

        // 如果时间状态传入格式不对,使其筛选条件失效
        if (!in_array($dateStatus, array(
            'order',
            'checkin',
            'checkout'
        ))) {
            $dateStatus = 'order';
        }
        
        $hotelId = $param['hotel'];
        $name = empty($param['name']) ? null : $param['name'];
        $room = empty($param['room']) ? null : $param['room'];
        $orderStatus = is_null($param['status']) ? null : $param['status'];
        $hotelChannelId = empty($param['channel']) ? null : $param['channel'];
        
        // 检查权限
        Vendor('phpExcel.PHPExcel');
        $phpExcel = new \PHPExcel();
        $objWriter = new \PHPExcel_Writer_Excel5($phpExcel);
        // 查询客栈数据
        $hotelEntityModel = D('HotelEntity');
        $hotelEntity = $hotelEntityModel->getInfo($hotelId);
        
        $orderLogic = A('Common/Order', 'Logic');
        try {
            $orderInfo = $orderLogic->getSubOrder($hotelId, null, $dateStatus, $startDate, $endDate, $room, $orderStatus, $hotelChannelId, $name, null, null, true);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }
        
        $adminLoginLogic = A('Common/AdminLogin', 'Logic');

        // 输出文件名
        $orderListString = '';
        switch (LANG_SET) {
            case 'en_us':
                $orderListString .= 'Order list';
                // 设置导出Excel标题
                $phpExcel->setActiveSheetIndex(0);
                $phpExcel->getActiveSheet()->setCellValue('A1', 'Input ime');
                $phpExcel->getActiveSheet()->setCellValue('B1', 'Guest');
                $phpExcel->getActiveSheet()->setCellValue('C1', 'Mobile phone');
                $phpExcel->getActiveSheet()->setCellValue('D1', 'Source');
                $phpExcel->getActiveSheet()->setCellValue('E1', 'check in/Check Out time');
                $phpExcel->getActiveSheet()->setCellValue('F1', 'Room number');
                $phpExcel->getActiveSheet()->setCellValue('G1', 'Amounts');
                $phpExcel->getActiveSheet()->setCellValue('H1', 'Order status');
                break;
            case 'zh_tw':
                $orderListString .= '訂單清單';
                // 设置导出Excel标题
                $phpExcel->setActiveSheetIndex(0);
                $phpExcel->getActiveSheet()->setCellValue('A1', '錄入時間');
                $phpExcel->getActiveSheet()->setCellValue('B1', '入住人');
                $phpExcel->getActiveSheet()->setCellValue('C1', '手機號');
                $phpExcel->getActiveSheet()->setCellValue('D1', '来源');
                $phpExcel->getActiveSheet()->setCellValue('E1', '入住/退房日期');
                $phpExcel->getActiveSheet()->setCellValue('F1', '房間號');
                $phpExcel->getActiveSheet()->setCellValue('G1', '金額');
                $phpExcel->getActiveSheet()->setCellValue('H1', '訂單狀態');
                break;
            default:
                $orderListString .= '订单列表';
                // 设置导出Excel标题
                $phpExcel->setActiveSheetIndex(0);
                $phpExcel->getActiveSheet()->setCellValue('A1', '录入时间');
                $phpExcel->getActiveSheet()->setCellValue('B1', '入住人');
                $phpExcel->getActiveSheet()->setCellValue('C1', '手机号');
                $phpExcel->getActiveSheet()->setCellValue('D1', '来源');
                $phpExcel->getActiveSheet()->setCellValue('E1', '入住/退房日期');
                $phpExcel->getActiveSheet()->setCellValue('F1', '房间号');
                $phpExcel->getActiveSheet()->setCellValue('G1', '金额');
                $phpExcel->getActiveSheet()->setCellValue('H1', '订单状态');
                break;
        }
        $outputFileName = $hotelEntity['name'] . date("Y.m.d") . $orderListString;
        
        
        // 数据输出格式处理
        $i = 0;
        foreach ($orderInfo['subOrder'] as $key => $order) {
            if ($type == 1 && $order['hour'] > 0 && $order['month'] > 0) {
                continue;
            } elseif ($type == 2 && $order['night'] > 0) {
                continue;
            } elseif ($type == 3 && $order['month'] == 0) {
                continue;
            }
            $createtime = date('m/d H:i', strtotime($order['createtime']));
            $startDate = date('m/d', strtotime($order['startdate']));
            $endDate = date('m/d', strtotime($order['checkoutdate']));
            $phpExcel->getActiveSheet()->setCellValue('A' . ($i + 2), $createtime);
            $mobile = array_diff(array_column($order['user'], 'mobile'), array(''));
            $phpExcel->getActiveSheet()->setCellValueExplicit('B' . ($key + 2), implode(',', array_column($order['user'], 'name')), \PHPExcel_Cell_DataType::TYPE_STRING);
            $phpExcel->getActiveSheet()->setCellValueExplicit('C' . ($key + 2), implode(',', $mobile), \PHPExcel_Cell_DataType::TYPE_STRING);
            $phpExcel->getActiveSheet()->setCellValue('D' . ($key + 2), $order['order']['channelName']);
            $phpExcel->getActiveSheet()->setCellValue('E' . ($key + 2), $startDate . '-' . $endDate);
            $phpExcel->getActiveSheet()->setCellValueExplicit('F' . ($key + 2), $order['roominfo_name'], \PHPExcel_Cell_DataType::TYPE_STRING);
            $phpExcel->getActiveSheet()->setCellValue('G' . ($key + 2), $order['payment']);
            $phpExcel->getActiveSheet()->setCellValue('H' . ($key + 2), $orderLogic->statusMap[LANG_SET][$order['status']]);
        }
        //调用输出excel
        phpExcelOutput($objWriter, $outputFileName);
    }

    /**
     * @添加订单
     * @modify songanwei 2016-01-15
     * @modify trainyao 2016-08-26 增加同住人
     */
    private function addOrder($type) {
        $params = I('post.');
        $hotelChannelId = $params['channel']; //来源渠道
        $hotelId = $params['hotel']; //客栈ID
        $payment = $params['payment']; //应付金额(若是会员下单,这是原价)
        $vip = $params['vip'];//原价(不是会员下单 则等于payment)
        $remark = $params['remark']; //备注
        $orderRecord = $params['detail'];
        $receives = $params['receive'];
        $checkIn = isset($params['checkIn']) ? $params['checkIn'] : 0;
        //检查参数
        $orderRecordValidateRule = array(
            'roomId' => 'notnull,notempty,id',
            'orderDate' => 'notnull,notempty',
            'nights' => 'notnull,bookNight',
            'payment' => 'notnull,decimal8_2',
            'users' => 'notnull,notempty',
            'hour' => 'bookHour',
            'month' => 'bookMonth',
        );
        $orderUserValidateRule = array(
            'name' => 'notnull,notempty,nameLength20',
            'identity' => 'IDCard',
        );
        foreach ($orderRecord as &$subOrderItem) {
            $validatePass = $this->ajaxValidateReturn($this->validateUtil, $subOrderItem, $orderRecordValidateRule);
            if (!$validatePass) {
                return;
            }
            foreach ($subOrderItem['users'] as &$orderUserItem) {
                $validatePass = $this->ajaxValidateReturn($this->validateUtil, $orderUserItem, $orderUserValidateRule);
                if (!$validatePass) {
                    return;
                }

                $orderUserItem['areacode'] = isset($orderUserItem['areaCode']) && !empty($orderUserItem['areaCode']) ? $orderUserItem['areaCode'] : '86';
                if (isset($orderUserItem['areaCode'])) unset($orderUserItem['areaCode']);
                if (isset($orderUserItem['mobile']) && $orderUserItem['mobile'] != '') {
                    $this->ajaxValidateReturn($this->validateUtil, $orderUserItem['mobile'], 'globalMobile',
                    array('globalMobile' => array('function', 'checkGlobalMobile,' . $orderUserItem['areacode'], '403,130,error'),
                    ));
                }

                // 组装订单用户数据
                $orderUserItem['idsex'] = '';
                $orderUserItem['idnation'] = '';
                $orderUserItem['idaddress'] = '';
            }
            unset($orderUserItem);
            if (isset($subOrderItem['month'])) {
                $subOrderItem['nights'] = getNight($subOrderItem['orderDate'], date('Y-m-d',strtotime('+' . $subOrderItem['month'] . 'months', strtotime($subOrderItem['orderDate']))));
            }
        }
        unset($subOrderItem);
        if ($remark) {
            $this->ajaxValidateReturn($this->validateUtil, $remark, "nameLength255");
        }

        // 会员卡信息
        $vipCard = array();
        if (isset($params['vipCard'])) {
            $vipCard = $params['vipCard'];
            $this->ajaxValidateReturn($this->validateUtil, $vipCard['cardMobile'], 'globalMobile', array('globalMobile' => array('function', 'checkGlobalMobile,' . $vipCard['cardAreaCode'], '403,130,error'),
                    ));
        }

        // 取出默认货币
        $currencyLogic = A('Common/Currency', 'Logic');
        $hotelDefaultCurrency = $currencyLogic->takeHotelCurrency($hotelId, true);
        $currencyId = !empty($hotelDefaultCurrency) ? $hotelDefaultCurrency[0]['currencyId'] : 8 ; // 8 = 人民币

        $deposit = 0.00; //押金
        $receipt = 0.00; //已收金额
        //计算总额
        foreach ($receives as $index => &$receive) {
            $isTrans = false;
            if ($currencyId != $receive['transCurrencyId'] && (double) $receive['value'] != 0) {
                $isTrans = true;
            }

            $receive['transBeforeValue'] = $receive['value'];
            if ($receive['category'] == 1) {
                // 价格汇率转换
                if ($isTrans) {
                    $receive['value'] = $currencyLogic->exchangeRates($receive['transCurrencyId'], $currencyId, $receive['value']);
                }

                $deposit+= $receive['value'];
            } else if ($receive['category'] == 0) {
                // 价格汇率转换
                if ($isTrans) {
                    $receive['value'] = $currencyLogic->exchangeRates($receive['transCurrencyId'], $currencyId, $receive['value']);
                }

                $receipt+= $receive['value'];
            } else if ($receive['type'] != 0) {
                // 价格汇率转换
                if ($isTrans) {
                    $receive['value'] = $currencyLogic->exchangeRates($receive['transCurrencyId'], $currencyId, $receive['value']);
                }

                // 其他消费 （不含待收款）
                $receipt+= $receive['value'];
                // 订单金额加上 其他消费
                $payment += $receive['value'];
            } else if ($receive['type'] == 0) {
                // 带收款 价格汇率转换
                if ($isTrans) {
                    $receive['value'] = $currencyLogic->exchangeRates($receive['transCurrencyId'], $currencyId, $receive['value']);
                }
            }

            //过滤数据
            if ((double) $receive['value'] == 0) {
                unset($receives[$index]);
            }
        }

        //过滤数据
        $payment = keepNumberInRange($payment);
        $deposit = keepNumberInRange($deposit);
        $receipt = keepNumberInRange($receipt);
        $orderLogic = A('Common/Order', 'Logic');
        // 判断是否检查当天之前的房间状态 即是否脏房、已预订或已入住 检查并返回数据
        if ($type == 2 && $checkIn == 1) {
            //查询该房间当天之前已预订或已入住的房间信息 是否脏房(checkIn==1在 addInfo里面 强制回滚)
            try {
                $dirtyData = $orderLogic->addInfo($hotelId, $hotelChannelId, $deposit, $payment, $receipt, $remark, $orderRecord, $receives, $type, 0, false, $checkIn);
            } catch (\Exception $e) {
                returnJson($e->getMessage());
                return;
            }

            if (!empty($dirtyData)) {
                // 组装返回数据 返回查询数据信息
                $roomDirty = array();
                foreach ($orderRecord as $orderKey => $orderItem) {
                    foreach ($dirtyData as $irtyKey => $dirtyItem) {
                        if ($irtyKey == 'orderRoomInfos') {
                            foreach ($dirtyItem as $listKey => $dirtyItemList) {
                                if ($orderItem['roomId'] == $dirtyItemList['roomId']) {
                                    $roomDirty['roomStatus'][$dirtyItemList['roomId']] = array(
                                        'rooId' => $dirtyItemList['roomId'],
                                        'roomName' => $dirtyItemList['roomName'],
                                        'status' => $dirtyItemList['status'],
                                    );
                                }
                            }
                            unset($dirtyItemList);
                        }
                    }
                    unset($dirtyItem);
                }
                unset($orderItem);

                $dirtyData['orderRoomInfos'] = array_values($roomDirty['roomStatus']);
                if (!empty($vipCard)) {
                    $dirtyData['vipCard'] = $vipCard;
                }

                returnJson(403, 308, $dirtyData);
            }

        }
        //检查并添加数据
        try {
            $data = $orderLogic->addInfo($hotelId, $hotelChannelId, $deposit, $payment, $receipt, $remark, $orderRecord, $receives, $type, 0, false, 0, 0, $vip, null, null, null, $vipCard);
        } catch (\Exception $e) {

            returnJson($e->getMessage());
            return;
        }

        // 处理数据
        foreach ($data as &$orderRoomData) {
            $orderRoomData['status'] = $orderRoomData['statusName'];
            unset($orderRoomData['statusName']);
        }
        unset($orderRoomData);

        //返回成功数据信息
        returnJson(200, 200, $data);
    }

    /**
     * 同意退款
     * @modify trainyao 2016-05-17    创建
     * @modify wenhui 2017-02-27    子订单的修改
     */
    public function agreeRefund() {
        $param = I('post.');
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'refund' => 'notnull,notempty,id',
            'price' => 'notnull,notempty,decimal8_2',
        );

        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (empty($validatePass)) {
            return;
        }

        // 校验订单是否在客栈内
        $hotelId = $param['hotel'];
        $refundId = $param['refund'];

        $orderRefundModel = D('OrderRefund');
        $orderRefundInfo = $orderRefundModel->getInfo($refundId);
        if (empty($orderRefundInfo) || $orderRefundInfo['hotelentity_id'] != $hotelId) {
            returnJson(403, 202);
            return;
        }
        $orderRoomId = $orderRefundInfo['orderroom_id'];

        // 校验是否有房间权限操作子订单
        $userId = getUserId();
        $adminAuthorityLogic = A('Common/AdminAuthority', 'Logic');
        if (!$adminAuthorityLogic->checkIsAdmin($userId, $hotelId)) {
            $accountLogic = A('Common/Account', 'Logic');
            $roomAuthority = $accountLogic->getAdminRoomAuthority($userId, $hotelId);

            // 筛选出有房间权限的子订单
            $orderRoomModel = D('OrderRoom');
            $orderRoomInfo = $orderRoomModel->getInfo($orderRoomId);
            $orderRoomInfo = fliterArrayByKey($orderRoomInfo, 'roominfo_id', $roomAuthority);
            if (empty($orderRoomInfo)) {
                returnJson(403, 202);
                return;
            }
        }

        // 查看是否有对应的代收记录,并记录代收ID
        $orderPayInfoModel = D('OrderPayInfo');
        $orderPayInfo = $orderPayInfoModel->getInfoByOrderMethod($orderRoomId);
        $payMethod = '现金';
        $receipted = false;
        $price = $param['price'];
        // 存在第三方收款记录且收款记录是畅联代收时,需要处理
        if (!empty($orderPayInfo) && ($orderPayInfo['type'] == PAY_TYPE_UCLBRT_ALIPAY || $orderPayInfo['type'] == PAY_TYPE_UCLBRT_WECHAT)) {
            $orderRoomModel = D('OrderRoom');
            $orderRoomInfoDetail = $orderRoomModel->getInfo($orderRoomId);
            $orderInfoModel = D('OrderInfo');
            $orderRoomInfoDetail = $orderInfoModel->getInfo($orderRoomInfoDetail[0]['orderinfo_id']);
            // 校验传入金额是否大于代收金额(如有义卖金额除去)
            $payfee = $orderRoomInfoDetail['charityprice'] == 0 ? $orderPayInfo['payfee'] : $orderPayInfo['payfee'] - $orderRoomInfoDetail['charityprice'];
            $payfee = number_format($payfee, 2, '.','');
            if ($price > $payfee) {
                returnJson(403, 503);
                return;
            }

            $receipted = true;
            switch ($orderPayInfo['paymethod']) {
                case ORDER_PAY_WECHAT:
                    $payMethod = '微信支付';
                    break;
                case ORDER_PAY_ALI:
                    $payMethod = '支付宝支付';
                    break;
                default:
                    break;
            }
        }

        // 获取支付方式在该客栈的支付方式id
        $hotelLogic = A('Common/Hotel', 'Logic');
        $hotelPay = $hotelLogic->getHotelPay($hotelId, false, 'zh_cn', true);
        $hotelPay = getArrayValueAsIndex($hotelPay, 'name');
        $hotelPayId = $hotelPay[$payMethod]['id'];

        // 执行退款
        $orderRoomModel = D('OrderRoom');
        $orderRoomModel->startTrans();
        $commit = true;

        // 返回子订单ids 
        $orderRoom = $orderRoomModel->getInfo($orderRoomId)[0];
        $orderRooms = $orderRoomModel->getInfoByOrder($orderRoom['orderinfo_id'], false);
        $orderRoomIds = array_column($orderRooms, 'id');

        // 执行取消订单逻辑 
        $orderLogic = A('Common/Order', 'Logic');
        try {
            $orderBookLogic = A('Common/OrderBook', 'Logic');
            // 获取子订单数据 组装数据格式
            $orderDetails = array();
            foreach ($orderRoomIds as $key => $orderRoomIdItem) {
                $orderRoomInfo = $orderBookLogic->getOrderDetail($orderRoomIdItem);
                if ($orderRefundInfo['type'] == REFUND_TYPE_CHECKOUT) {
                    $orderDetailItem = array(
                        'orderRoomId' => $orderRoomInfo['id'],
                        'orderDate' => substr($orderRoomInfo['startdate'], 0, 10),
                        'roomId' => $orderRoomInfo['roominfo_id'],
                        'nights' => $orderRoomInfo['realnight'],
                        'payment' => $orderRoomInfo['payment'],
                        'users' => array(),
                    );
                    array_push($orderDetails, $orderDetailItem);
                }
            }

            // 子订单共同数据
            $orderRoomInfo = $orderBookLogic->getOrderDetail($orderRoomId);

            // 无代收记录,是否是会员卡支付 (修改会员卡)
            if (!$receipted) {
                $customerLogic = A('Common/Customer', 'Logic');
                $payMethod = '会员卡';
                $hotelPayId = $hotelPay[$payMethod]['id'];
                $orderInfoId = $orderRoom['orderinfo_id'];
                // 校验传入金额是否大于代收金额(如有义卖金额除去)
                if ($price > $orderRefundInfo['price']) {
                    returnJson(403, 503);
                    return;
                }

                $agreeResult = $customerLogic->refundVipCardInfo($hotelId, $orderRoomInfo['order']['mobile'], $orderRoomInfo['order']['areacode'], $orderInfoId, $hotelPayId, $price);
                if (empty($agreeResult)) {
                    $commit = false;
                }
            }

            // [提前退房退款]进行修改订单,[退款申请退款]进行取消订单
            switch ($orderRefundInfo['type']) {
                case REFUND_TYPE_APPLY:
                    $price = (double)$price;
                    $agreeResult = $orderLogic->cancelOrder($hotelId, $orderRoomInfo['order']['id'], $orderRoomIds, ORDER_CHANGE_WEB, null, null, -$price, $hotelPayId, null, null, 'multiTransMode');
                    break;
                case REFUND_TYPE_CHECKOUT:
                    foreach ($orderDetails as $key => &$orderDetailsItem) {
                        foreach ($orderRoomInfo['user'] as $orderUserItem) {
                            array_push($orderDetailsItem['users'], array(
                                'name' => $orderUserItem['name'],
                                'mobile' => $orderUserItem['mobile'],
                                'identity' => $orderUserItem['identity'],
                                'orderUser' => $orderUserItem['id'],
                            ));
                        }
                        unset($orderUserItem);
                    }
                    unset($orderDetailsItem);

                    // 获取客栈默认货币
                    $currencyLogic = A('Common/Currency', 'Logic');
                    $hotelDefaultCurrency = $currencyLogic->takeHotelCurrency($orderRoomInfo['order']['hotelentity_id'], true);
                    $currencyId = !empty($hotelDefaultCurrency) ? $hotelDefaultCurrency[0]['currencyId'] : 8 ; // 8 = 人民币

                    $receives = array(array(
                        'category' => PAY_CHANGE_REFUND,
                        'type' => $hotelPayId,
                        'value' => $price,
                        'transBeforeValue' => $price,
                        'transCurrencyId' => $currencyId,
                    ));
                    $agreeResult = $orderLogic->saveInfo($hotelId, $orderRoomInfo['order']['id'], $orderRoomInfo['order']['hotelchannel_id'], 0, 0, null, $orderDetails, $receives, ORDER_CHANGE_WEB, null, 'multiTransMode');
                    break;
                default:
                    break;
            }
        } catch (\Exception $e) {
            $orderRoomModel->rollback();
            returnJson($e->getMessage());
            $commit = false;
            return;
        }

        // 执行订单退款记录逻辑 
        $orderRefundLogic = A('Common/OrderRefund', 'Logic');
        try {
            $agreeResult = $orderRefundLogic->agreeRefund($refundId, $price, true);
        } catch (\Exception $e) {
            $orderRoomModel->rollback();
            returnJson($e->getMessage());
            $commit = false;
            return;
        }

        // 无代收记录,操作完成
        if (!$receipted) {
            if (!$commit) {
                $orderRoomModel->rollback();
                returnJson(500, 506);
                return;
            }
            $orderRoomModel->commit();
            returnJson(200, 200);
            return;
        }

        // 有代收记录,修改代收记录退款字段
        $agreeResult = $orderPayInfoModel->saveInfo($orderPayInfo['id'], $price);
        if (empty($agreeResult)) {
            $commit = false;
        }

        if ($commit) {
            // 有代收记录,对应平台退款
            $fileLog = new \Org\Util\FileLog();
            $refundFee = (double)$price;
            if ($orderPayInfo['paymethod'] == ORDER_PAY_WECHAT) {
                Vendor('Wechat.WxPayApi');
                $wechatConfig = C('WECHAT_PAY_CONFIG');
                $qrWechatConfig = C('QR_WECHAT_PAY_CONFIG');
                $wechatConfigMchid = $orderPayInfo['wechatpayapp'] == PAY_QRCLIENT_APP ? $qrWechatConfig['mchid'] : $wechatConfig['mchid'];
                $transaction_id = $orderPayInfo['tradenumber'];
                $totalFee = (double)$orderPayInfo['payfee'] * 100;
                $refundFee = $refundFee * 100;

                $input = new \WxPayRefund();
                $input->SetTransaction_id($transaction_id);
                $input->SetTotal_fee($totalFee);
                $input->SetRefund_fee($refundFee);
                /*$input->SetOut_refund_no($wechatConfig['mchid'] . date("YmdHis"));
                $input->SetOp_user_id($wechatConfig['mchid']);*/
                $input->SetOut_refund_no($wechatConfigMchid . date("YmdHis"));
                $input->SetOp_user_id($wechatConfigMchid);

                try {
                    $agreeResult = \WxPayApi::refund($input, 6, $wechatConfigMchid);
                } catch (\Exception $e) {
                    $fileLog->write('订单退款调用抛异常:' . $e->errorMessage() . '-' . $transaction_id . '-' . $totalFee . '-' . $refundFee, 1, RUNTIME_PATH . "Logs/Home/WechatRefund/" . date('Y-m-d') . ".log");
                    $commit = false;
                    $orderRoomModel->rollback();
                    returnJson(500, 506);
                    return;
                }

                if (!isset($agreeResult['result_code']) || $agreeResult['result_code'] != 'SUCCESS') {
                    $fileLog->write('订单退款调用失败:' . $agreeResult['return_msg'] . '-' . $agreeResult['err_code'] . '-' . $agreeResult['err_code_des']  . '-' . $transaction_id . '-' . $totalFee . '-' . $refundFee, 1, RUNTIME_PATH . "Logs/Home/WechatRefund/" . date('Y-m-d') . ".log");
                    $commit = false;
                    $orderRoomModel->rollback();
                    returnJson(500, 506);
                    return;
                }
            } else if ($orderPayInfo['paymethod'] == ORDER_PAY_ALI) {
                vendor('Ali.AopClient');
                vendor('Ali.request.AlipayTradeRefundRequest');

                $aliConfig = C('ALIPAY_CONFIG');
                $aop = new \Vendor\Ali\AopClient();
                $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
                $aop->appId = $aliConfig['appId'];
                $aop->rsaPrivateKeyFilePath = '../private/aliPayKey/private_key.pem';
                $aop->alipayPublicKey='../private/aliPayKey/ali_aes_public_key.pem';
                $aop->apiVersion = '1.0';
                $aop->postCharset='UTF-8';
                $aop->format='json';
                $request = new \Vendor\Ali\AlipayTradeRefundRequest();
                $tradeNumber = $orderPayInfo['tradenumber'];
                $outRequestNo = $orderPayInfo['outtrademumber'] . date('YmdHis');
                $request->setBizContent('{
                    "trade_no":"' . $tradeNumber . '",
                    "refund_amount":' . $refundFee . ',
                    "refund_reason":"订单退款' . $refundFee . '元",
                    "out_request_no":"' . $outRequestNo . '"
                }');

                try {
                    $agreeResult = $aop->execute($request);
                } catch (\Exception $e) {
                    $fileLog->write('订单退款调用抛异常:' . $e->errorMessage() . '-' . $tradeNumber . '-' . $refundFee, 1, RUNTIME_PATH . "Logs/Home/AliRefund/" . date('Y-m-d') . ".log");
                    $commit = false;
                    $orderRoomModel->rollback();
                    returnJson(500, 506);
                    return;
                }

                if ($agreeResult->alipay_trade_refund_response->code != '10000') {
                    $commit = false;
                    $fileLog->write('订单退款调用失败:' . $tradeNumber . '-' . $refundFee . '-' . $agreeResult->alipay_trade_refund_response->code . '-' . $agreeResult->alipay_trade_refund_response->msg . '-' . $agreeResult->alipay_trade_refund_response->sub_code . '-' . $agreeResult->alipay_trade_refund_response->sub_msg, 1, RUNTIME_PATH . "Logs/Home/AliRefund/" . date('Y-m-d') . ".log");
                }
            }
        }

        if (!$commit) {
            $orderRoomModel->rollback();
            returnJson(500, 506);
            return;
        }
        
        $orderRoomModel->commit();
        returnJson(200, 200);
    }

    /**
     * 退款驳回
     * @modify trainyao 2016-05-17    创建
     */
    public function refuseRefund() {
        $param = I('post.');
        
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'orderRoomId' => 'notnull,notempty,id',
            'apply' => 'notnull,notempty,nameLength50',
        );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (empty($validatePass)) {
            return;
        }

        // 校验是否有房间权限操作子订单
        $hotelId = $param['hotel'];
        $orderRoomId = $param['orderRoomId'];
        $userId = getUserId();
        $adminAuthorityLogic = A('Common/AdminAuthority', 'Logic');
        if (!$adminAuthorityLogic->checkIsAdmin($userId, $hotelId)) {
            $accountLogic = A('Common/Account', 'Logic');
            $roomAuthority = $accountLogic->getAdminRoomAuthority($userId, $hotelId);

            // 筛选出有房间权限的子订单
            $orderRoomModel = D('OrderRoom');
            $orderRoomInfo = $orderRoomModel->getInfo($orderRoomId);
            $orderRoomInfo = fliterArrayByKey($orderRoomInfo, 'roominfo_id', $roomAuthority);
            if (empty($orderRoomInfo)) {
                returnJson(403, 202);
                return;
            }
        }
        
        // 校验订单是否在客栈内
        $orderLogic = A('Common/Order', 'Logic');
        $inHotel = $orderLogic->checkSubOrderInHotel($orderRoomId, $hotelId);
        if (empty($inHotel)) {
            returnJson(403, 202);
            return;
        }

        // 执行订单退款驳回逻辑 
        $orderRefundLogic = A('Common/OrderRefund', 'Logic');
        $apply = $param['apply'];
        try {
            $agreeResult = $orderRefundLogic->refuseRefund($orderRoomId, $apply);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }

        returnJson(200, 200);
    }

    /**
     * 打印获取房间二维码字符串
     * @modify trainyao 2016-08-16    创建
     */
    public function printQrcode() {
        $param = I('post.');
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'order' => 'notnull,notempty,id',
            'subOrder' => 'notnull',
            'lost' => 'notnull,notempty,booleanInt',
        );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (empty($validatePass)) {
            return;
        }
        
        $hotelId = $param['hotel'];
        $adminId = getUserId();        
        
        $subOrderInfo = $param['subOrder'];
        $validateRule = array(
            'id' => 'notnull,notempty,id',
            'userRoom' => 'notnull',
        );
        foreach ($subOrderInfo as $index => $subOrderInfoItem) {
            $validatePass = $this->ajaxValidateReturn($this->validateUtil, $subOrderInfoItem, $validateRule);
            if (empty($validatePass)) {
                return;
                break;
            }
            if (!empty($subOrderInfoItem['userRoom'])) {
                foreach ($subOrderInfoItem['userRoom'] as $userRoomIdItem) {
                    $validatePass = $this->ajaxValidateReturn($this->validateUtil, $userRoomIdItem, 'id');
                    if (empty($validatePass)) {
                        return;
                        break;
                    }
                }
                unset($userRoomIdItem);
            } else {
                unset($subOrderInfo[$index]);
            }
        }
        unset($subOrderInfoItem);
        $subOrderInfo = array_values($subOrderInfo);

        // 校验订单是否在客栈内
        $orderId = $param['order'];
        $orderLogic = A('Common/Order', 'Logic');
        $orderInHotel = $orderLogic->checkOrderInHotel($hotelId, $orderId);
        if (!$orderInHotel) {
            returnJson(403, 202);
            return;
        }

        try {
            $orderInfo = $orderLogic->getOrderInfo($hotelId, array($orderId));
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }
        $checkinType = $orderInfo[0]['rooms'][0]['hour'] > 0 ? 1 : 0;
        $orderRoomsInfo = getArrayValueAsIndex($orderInfo[0]['rooms'], 'id');
        // 校验传入的子订单ID是否都合法
        if (!empty(array_diff(array_column($subOrderInfo, 'id'), array_keys($orderRoomsInfo)))) {
            returnJson(403, 202);
            return;
        }
        // 获取客栈最迟退房时间
        $hotelLogic = A('Common/Hotel', 'Logic');
        $hotelBookDetail = $hotelLogic->getHotelBookingDetail($hotelId);
        $hotelCheckoutTime = isset($hotelBookDetail['checkouttime']) ? $hotelBookDetail['checkouttime'] : '12:00';
        $hotelCheckinTime = isset($hotelBookDetail['checkintime']) ? $hotelBookDetail['checkintime'] : '14:00';
        $canPreGetCard = date('H') < substr($hotelCheckinTime, 0, 2) ? true : false;

        // 获取父订单信息,生成需要获取二维码的订单数据
        $bpassLogic = A('Common/Bpass', 'Logic');
        $bpassSetting = $bpassLogic->getSetting();
        $defaultString = $bpassSetting['printdefaultstring'];
        $roomData = array();
        $returnData = array(
            'cardData' => array(),
        );
        $currentDateTimestamp = strtotime(date('Y-m-d'));
        $userRoomIds = array();

        // 判断订单情况,生成需要前往获取二维码的数据和读取默认字符串的数据
        foreach ($subOrderInfo as $printSubOrderInfoItem) {
            $subOrderItem = $orderRoomsInfo[$printSubOrderInfoItem['id']];
            // 校验传入的userRoomId是否都合法
            if (!empty(array_diff($printSubOrderInfoItem['userRoom'], array_column($subOrderItem['user'], 'userroom_id')))) {
                returnJson(403, 202);
                return;
                break;
            }

            // 记录userRoomId,用来增加用户打印次数
            $userRoomIds = array_merge($userRoomIds, $printSubOrderInfoItem['userRoom']);

            // 已入住的订单才进行打印房卡
            if ($subOrderItem['status'] == ORDER_CHECKINED || $subOrderItem['status'] == ORDER_SHOULD_CHECKOUT) {
                // 不允许打印未来房卡(当前时间在入住退房时间内才前往获取房卡,否则使用默认字符串)
                if ($checkinType === 1){
                    array_push($roomData, array(
                        'roomId' => $subOrderItem['roominfo_id'],
                        'roomName' => $subOrderItem['roominfo_name'],
                        'startdate' => substr($subOrderItem['startdate'], 0, 16),
                        'enddate' => substr($subOrderItem['enddate'], 0, 16),
                        'orderRoomId' => $subOrderItem['id'],
                    ));
                } elseif (strtotime($subOrderItem['startdate']) <= $currentDateTimestamp && strtotime($subOrderItem['enddate']) >= $currentDateTimestamp) {
                    // 已入住,今天在入住日期与退房日期范围内的订单,需要计算是否能提前入住
                    array_push($roomData, array(
                        'roomId' => $subOrderItem['roominfo_id'],
                        'roomName' => $subOrderItem['roominfo_name'],
                        'startdate' => $canPreGetCard ? $subOrderItem['startdate'] : substr($subOrderItem['startdate'], 0, 11) . $hotelCheckinTime,
                        'enddate' => $canPreGetCard ? $subOrderItem['enddate'] : substr($subOrderItem['enddate'], 0, 11) . $hotelCheckoutTime,
                        'orderRoomId' => $subOrderItem['id'],
                    ));
                    
                } else {
                    // 不能发房卡的订单,二维码为bpass设置的字符串
                    $returnData['cardData'][$subOrderItem['id']] = array(
                        'cardString' => $defaultString,
                        'startTime' => substr($subOrderItem['startdate'], 0, 11) . $hotelCheckinTime,
                        'endTime' => substr($subOrderItem['enddate'], 0, 11) . $hotelCheckoutTime,
                        'type' => PRINTQRCODE_TYPE_STRING,
                    );
                }
            }
        }
        unset($printSubOrderInfoItem);

        // 检查是否到获取房卡时间
        $userRoomModel = D('UserRoom');
        $userRoomInfo = $userRoomModel->getInfo(array_values(array_unique($userRoomIds)));
        if (!empty($userRoomInfo)) {
            $preRoomData = getArrayValueAsIndex($roomData, 'roomId');
            $currentTimestamp = time();
            foreach ($userRoomInfo as $key => $userRoom) {
                if ($currentTimestamp < strtotime($userRoom['startdate'])) {
                    $roomName = isset($preRoomData[$userRoom['roominfo_id']]['roomName']) ? $preRoomData[$userRoom['roominfo_id']]['roomName'] : '';
                    returnJson(403, 602, $roomName);
                }
            }
            unset($userRoom);
        }

        // 获取可提前发卡的房间
        if (!empty($roomData) && $canPreGetCard) {
            $currentHourMinute = date('H:i');
            $canPreGetCardIndex = $orderLogic->getCanPreGetCardIndex($hotelId, $roomData);
            foreach ($roomData as $index => &$roomDataItem) {
                if ($checkinType === 1){
                    continue;
                } elseif (in_array($index, $canPreGetCardIndex)) {
                    $roomDataItem['startdate'] = substr($roomDataItem['startdate'], 0, 11) . $currentHourMinute;
                    $roomDataItem['enddate'] = substr($roomDataItem['enddate'], 0, 11) . $hotelCheckoutTime;
                } else {
                    $roomDataItem['startdate'] = substr($roomDataItem['startdate'], 0, 11) . $hotelCheckinTime;
                    $roomDataItem['enddate'] = substr($roomDataItem['enddate'], 0, 11) . $hotelCheckoutTime;
                }
            }
            unset($roomDataItem);
        }

        // 获取房间二维码数据
        $lost = $param['lost'] == ENABLE ? true : false;
        if (!empty($roomData)) {
            $roomLogic = A('Common/Room', 'Logic');
            try {
                $qrcodeData = $roomLogic->getQrcode($hotelId, $roomData, $lost);
            } catch (\Exception $e) {
                returnJson($e->getMessage());
                return;
            }
            foreach ($roomData as $roomDataItem) {
                $returnData['cardData'][$roomDataItem['orderRoomId']] = array(
                    'cardString' => $qrcodeData[$roomDataItem['roomId']]['cardString'],
                    'startTime' => $roomDataItem['startdate'],
                    'endTime' => $roomDataItem['enddate'],
                    'type' => $qrcodeData[$roomDataItem['roomId']]['type'],
                );
            }
            unset($roomDataItem);

        }

        // 用户增加打印次数
        if (!empty($userRoomIds)) {
            try {
                $orderLogic->addPrintCount(array_values(array_unique($userRoomIds)));
            } catch (\Exception $e) {
                returnJson(500, 512);
                return;
            }
        }

        // 获取客栈数据
        $hotelInfo = $hotelLogic->getHotelByHotelId(array($hotelId));
        $returnData['hotelId'] = $hotelId;
        $returnData['hotelName'] = $hotelInfo[0]['name'];
        
        //处理旧数据
        
        $returnData['cookie1'] = I('cookie.printSettingHint1');
        $returnData['cookie2'] = I('cookie.printSettingHint2');
        
        // 获取打印设置
        $printSettingModel = D('PrintSetting');
        $printSetting = $printSettingModel->getSetting($hotelId, 2);
        if ($printSetting)
        {
            unset($printSetting['id']);
            unset($printSetting['hotelentity_id']);
            unset($printSetting['printtype']);
        }
        else
        {
            $data['hotelentity_id'] = $hotelId;
            $data['printtype'] = 2;
            $data['printerpaper'] = 'X58';
            $data['tips1'] = I('cookie.printSettingHint1');
            $data['tips2'] = I('cookie.printSettingHint2');
            $printSettingModel->data($data)->add();
            $printSetting = $printSettingModel->getSetting($hotelId, 2);
            unset($printSetting['id']);
            unset($printSetting['hotelentity_id']);
            unset($printSetting['printtype']);
        }
        $returnData['printSetting'] = $printSetting;

        $returnData['isClientAvailable'] = false;
        $HotelEntityModel = D('HotelEntity');
        $hotelInfo = $HotelEntityModel->getInfo($hotelId);
        if(! empty($hotelInfo['clientswitch']))
        {
	        if(!checkClientLogin($adminId))
	        {
	            returnJson(403, 10001);
	        }
            $returnData['isClientAvailable'] = true;
            $isFirst = true;
            foreach ($roomData as $room)
            {
                $suborder_info = $orderRoomsInfo[$room['orderRoomId']];
                foreach ($suborder_info['user'] as $room_user)
                {
                    $args["hotel_name"] = $returnData['hotelName'];
                    $args["card_data"] = $qrcodeData[$room['roomId']]['cardString'];
                    $args["room_name"] = $suborder_info['roominfo_name'];
                    $args["guest_name"] = $room_user['name'];
                    $args["start_time"] = $room['startdate'];
                    $args["end_time"] = $room['enddate'];
                    $args["deposit_amount"] = $orderInfo[0]['deposit'];
                    $args["tips1"] = $printSetting['tips1'];
                    $args["tips2"] = $printSetting['tips2'];
                    $args["lost"] = empty($param['lost']) ? false : true;
                    $args["preview"] = $isFirst;
                    $isFirst = false;
                    sendTcpClientMsg($adminId, 'print_meizhu_qrcode', $args);
                }
            }
        }

        returnJson(200, 200, $returnData);
    }
    /**
     * 获取改价日志
     * @modify zhangzhen 2017-03-02    创建
     */
    public function changeReport() {
        $param = I('post.');
        $validateRule = array(
            'hotel' => 'notempty,id',
            'roomtype' => 'notempty,id',
            'creator' => 'notempty,id',
            'startDate' => 'notempty,isDate',
            'endDate' => 'notempty,isDate',
            'pricetype' => 'notempty,natureNumber',
            'sale' => 'notempty,natureNumber',
            'currentPage' => 'notempty,natureNumber',
            );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (empty($validatePass)) {
            return;
        }
        $hotel = $param['hotel'];
        $roomtype = $param['roomtype'] ? $param['roomtype'] : null;
        $creator = $param['creator'] ? $param['creator'] : null;
        $pricetype = $param['pricetype'] ? $param['pricetype'] : null;
        $sale = $param['sale'] ? $param['sale'] : null;
        $startDate = $param['startDate'];
        $endDate = $param['endDate'];
        $pageIndex = isset($param['currentPage']) ? $param['currentPage'] : 1;
        $pageSize = C('PAGE_SIZE');
        $priceRecordModel = D('PriceRecord');
        $returnItem = $priceRecordModel->getInfoByCondition($hotel, $roomtype, $creator, $pricetype, $sale, $startDate, $endDate, $pageIndex, $pageSize);
        // 客栈时区
        $utc = new \Org\Util\UTC();
        $hotelEntityModel = D('HotelEntity')->getInfo($hotel);
        //获取区号时区数据
        $HotelLogic = A('Common/Hotel', 'Logic');
        $universalTimeData = $HotelLogic->universalTimeList();
        $universalTimeData = getArrayValueAsIndex($universalTimeData, 'universalTimeId');
        $universalTimeTimezone = $universalTimeData[$hotelEntityModel['universaltime_id']]['universalTimeTimezone'];
        $universalTimeTimezone = isset($universalTimeTimezone) && !is_null($universalTimeTimezone) ? $universalTimeTimezone : 'GMT+8';
        foreach ($returnItem['data'] as &$data) {
            $data['createtime'] = $utc->toTimeZone($data['createtime'], 'Asia/Shanghai' , $universalTimeTimezone);
        }
        returnJson(200, 200, array(
            'item' => $returnItem['data'],
            'page' => array(
                'currentPage' => $pageIndex,
                'size' =>  $pageSize,
                'total' =>  ceil($returnItem['count'] / $pageSize),
                'totalCount' => $returnItem['count'],
            ),
        ));
    }
    
    /**
     * 获取改价日志搜索title
     * @modify zhangzhen 2017-03-02    创建
     */
    public function changeReportTitle() {
        $param = I('post.');
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
        );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (empty($validatePass)) {
            return;
        }
        $hotel = $param['hotel'];
        $priceRecordModel = D('PriceRecord');
        $roomType = $priceRecordModel->GroupByRoomType($hotel);
        $creator = $priceRecordModel->GroupByCreator($hotel);
        returnJson(200, 200, [
                'roomType' => $roomType,
                'creator' => $creator,
            ]);
    }
    
    /**
     * @description 打印订单
     * @modify paddy 2017-06-02
     */
    public function printOrder()
    {
        $param = I('post.');
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'order' => 'notnull,notempty,id',
            'printType' => 'notnull,notempty,id'
        );
        $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
    
        $hotelId = $param['hotel'];
        $adminId = getUserId();
        
        $printType = $param['printType'];
        $printSettingModel = D('PrintSetting');
        $printSetting = $printSettingModel->getSetting($hotelId, $printType);
        if (! empty($printSetting) && is_array($printSetting))
        {
            unset($printSetting['id']);
            unset($printSetting['hotelentity_id']);
            unset($printSetting['printtype']);
        }else
        {
            $data['hotelentity_id'] = $hotelId;
            $data['printtype'] = $printType;
            $data['printerpaper'] = $printType == 1 ? 'A4' : 'X58';
            $data['tips1'] = I('cookie.printSettingHint1');
            $data['tips2'] = I('cookie.printSettingHint2');
            $printSettingModel->data($data)->add();
            $printSetting = $printSettingModel->getSetting($hotelId, $printType);
            unset($printSetting['id']);
            unset($printSetting['hotelentity_id']);
            unset($printSetting['printtype']);
        }
        
        $orderLogic = A('Common/Order', 'Logic');
        try {
            $orderInfo = $orderLogic->getOrderInfo($hotelId, array($param['order']));
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }
    
        $hotelEntityModel = D('HotelEntity');
        $hotelInfo = $hotelEntityModel->getInfo($hotelId);
        if(empty($hotelInfo)){
            returnJson(403, 403, 'hotel not found!');
        }
        $printSetting['hotelName'] = $hotelInfo['name'];    
        $printSetting['printTime'] = date('Y-m-d H:i:s');  
        
        $hotelLogic = A('Common/Hotel', 'Logic');
        $hotelBookDetail = $hotelLogic->getHotelBookingDetail($hotelId);
        $hotelCheckoutTime = isset($hotelBookDetail['checkouttime']) ? $hotelBookDetail['checkouttime'] : '12:00';
        $hotelCheckinTime = isset($hotelBookDetail['checkintime']) ? $hotelBookDetail['checkintime'] : '14:00';
                
        $printSetting['isClientAvailable'] = false;
        if(! empty($hotelInfo['clientswitch']))
        {
	        if(!checkClientLogin($adminId))
	        {
	            returnJson(403, 10001);
	        }
            $printSetting['isClientAvailable'] = true;
            $rooms = array();
            foreach ($orderInfo[0]['rooms'] as $room) {

                $checkintime = date('Y/m/d', strtotime($room['startdate'])) . ' ' . $hotelCheckinTime;
                if ($room['checkindate'] != '0000-00-00 00:00:00') {
                    $checkintime = date('Y/m/d H:i', strtotime($room['checkindate']));
                }
                $checkoutdate = date('Y/m/d', strtotime($room['checkoutdate'])) . ' ' . $hotelCheckoutTime;
                if ($room['printcheckoutdate'] != '0000-00-00 00:00:00') {
                    $checkoutdate = date('Y/m/d H:i', strtotime($room['printcheckoutdate']));
                }
                
                $rooms[] = array(
                    "name" => $room['roominfo_name'],
                    "start_date" => $checkintime,
                    "end_date" => $checkoutdate,
                    "days" => $room['night'],
                    "price" => $room['payment']
                );
            }
            $paid = array();
            foreach ($orderInfo[0]['payHistory']['receivedInfo'] as $p)
            {
                $paid[] = array(
                    'type' => $p['type'],
                    'name' => $p['name'],
                    'pay' => $p['pay'],
                );                
            }
            $refund = array();
            foreach ($orderInfo[0]['payHistory']['refundInfo'] as $r)
            {
                $refund[] = array(
                    'type' => $r['type'],
                    'name' => $r['name'],
                    'pay' => $r['pay'],
                );                
            }
            $args["rooms"] = $rooms;
            $args["paid"] = $paid;
            $args["refund"] = $refund;
            $args["hotel_name"] = $hotelInfo['name'];
            $args["guest_name"] = $orderInfo[0]['name'];
            $args["areacode"] = empty($printSetting['printmobile'])||empty($orderInfo[0]['mobile']) ? '' : "+{$orderInfo[0]['areacode']}";
            $args["mobile"] = empty($printSetting['printmobile']) ? '******' : $orderInfo[0]['mobile'];
            $args["certificate_no"] = empty($printSetting['printidentity']) ? '******' : $orderInfo[0]['identity'];
            $args["order_price"] = $orderInfo[0]['orig'];
            $args["discount_price"] = $orderInfo[0]['payment'];
            $args["received_deposit"] = $orderInfo[0]['deposit'];
            $args["received_money"] = $orderInfo[0]['receipt'];
            $args["remark"] = $orderInfo[0]['remark'];
            $args["tips1"] = $printSetting['tips1'];
            $args["tips2"] = $printSetting['tips2'];
            $args["copies"] = (int) $printSetting['printtimes'];
            $args["preview"] = empty($printSetting['preview']) ? false : true;
            $cmd = 'print_meizhu_order_x58';
            if($printSetting['printerpaper'] == 'A4')
            {
                $cmd = 'print_meizhu_order_a4';
            }
            sendTcpClientMsg($adminId, $cmd, $args);
        }
        returnJson(200, 200, $printSetting);
    }
    /**
     * @description 获取分享卡
     * @modify zhangzhen 2017-03-09
     */
    public function getShareHistory() {
        $params = I('post.');

        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'orderRoomId' => 'notnull,notempty,id',
        );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $params, $validateRule);
        if (empty($validatePass)) {
            return;
        }
        $hotelId = $params['hotel'];
        $orderRoomId = $params['orderRoomId'];
        $shareCardRecordModel = D('ShareCardRecord');
        $shareCardRecords = $shareCardRecordModel->getInfoByOrderRoomId($orderRoomId);
        //屏蔽联系人
        $adminAuthorityLogic = A('Common/AdminAuthority', 'Logic');
        $canSeeMobile = $adminAuthorityLogic->check($hotelId, null, AUTHORITY_CONTACT_INFO_BLOCK);
        if (!$canSeeMobile) {
            foreach ($shareCardRecords as &$shareCardRecord) {
                $shareCardRecord['mobile'] = substr($shareCardRecord['mobile'], 0, 3) . '********';
            }
            unset($shareCardRecord);
        }
        foreach ($shareCardRecords as &$r) {
            if($r['opfrom']==1)
            {
                $r['by'] = $r['bookuname'];
            }
            unset($r['bookuname']);
        }
        unset($r);
        returnJson(200, 200, $shareCardRecords);
    }
    /**
     * 获取将要写RF卡的数据
     * @modify paddy 2017-01-23    创建
     */
    public function getRFData() 
    {
        $param = I('post.');
        
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'order' => 'notnull,notempty,id',
            'subOrder' => 'notnull,notempty,id',
            'userRoom' => 'notnull,notempty,id',
            'lost' => 'notnull,notempty,booleanInt',            
        );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (empty($validatePass)) {
            return;
        }
        
        $hotelId = $param['hotel'];
        $adminId = getUserId();

        // 获取客栈同步锁掌柜集群号
        $hotelLogic = A('Common/Hotel', 'Logic');
        $hotelInfo = $hotelLogic->getHotelByHotelId($hotelId);
        if (empty($hotelInfo[0]['communityno'])) {
            returnJson(500, 509);
            return;
        }
        
        // 校验订单是否在客栈内
        $orderId = $param['order'];
        $orderLogic = A('Common/Order', 'Logic');
        $orderInHotel = $orderLogic->checkOrderInHotel($hotelId, $orderId);
        if (!$orderInHotel) {
            returnJson(403, 202);
            return;
        }
        
        try {
            $orderInfo = $orderLogic->getOrderInfo($hotelId, array($orderId));
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }
        $checkinType = $orderInfo[0]['rooms'][0]['hour'] > 0 ? 1 : 0;
        $orderInfo = getArrayValueAsIndex($orderInfo[0]['rooms'], 'id');
        
        // 校验传入的子订单ID是否都合法
        $subOrderId = $param['subOrder'];
        if (!isset($orderInfo[$subOrderId])) {
            returnJson(403, 202);
            return;
        }
        
        $subOrderInfo = $orderInfo[$subOrderId];
        // 获取客栈最迟退房时间
        $hotelBookDetail = $hotelLogic->getHotelBookingDetail($hotelId);
        $hotelCheckoutTime = isset($hotelBookDetail['checkouttime']) ? $hotelBookDetail['checkouttime'] : '12:00';
        $hotelCheckinTime = isset($hotelBookDetail['checkintime']) ? $hotelBookDetail['checkintime'] : '14:00';
        $canPreGetCard = date('H') < substr($hotelCheckinTime, 0, 2) ? true : false;
        $roomData = array();
        $currentDateTimestamp = strtotime(date('Y-m-d'));
        $currentTimestamp = time();
        if($subOrderInfo['status'] == ORDER_CHECKINED){
            //鐘點房不提前拿卡
            if ($checkinType === 1 && strtotime($subOrderInfo['startdate']) <= $currentTimestamp && strtotime($subOrderInfo['enddate']) >= $currentTimestamp) {
                array_push($roomData, array(
                    'roomId' => $subOrderInfo['roominfo_id'],
                    'startdate' => substr($subOrderInfo['startdate'], 0, 16),
                    'enddate' => substr($subOrderInfo['enddate'], 0, 16),
                    'orderRoomId' => $subOrderInfo['id'],
                ));
            } elseif (strtotime($subOrderInfo['startdate']) <= $currentDateTimestamp && strtotime($subOrderInfo['enddate']) >= $currentDateTimestamp) {
                // 已入住,今天在入住日期与退房日期范围内的订单,需要计算是否能提前入住
                array_push($roomData, array(
                    'roomId' => $subOrderInfo['roominfo_id'],
                    'startdate' => $canPreGetCard ? $subOrderInfo['startdate'] : substr($subOrderInfo['startdate'], 0, 11) . $hotelCheckinTime,
                    'enddate' => $canPreGetCard ? $subOrderInfo['enddate'] : substr($subOrderInfo['enddate'], 0, 11) . $hotelCheckoutTime,
                    'orderRoomId' => $subOrderInfo['id'],
                ));
            }
        }

        if(empty($roomData)){
            returnJson(403, 202);
            return;
        }
        
        if ($canPreGetCard) {
            $canPreGetCardIndex = $orderLogic->getCanPreGetCardIndex($hotelId, $roomData);
            $currentHourMinute = date('H:i');
            foreach ($roomData as $index => &$roomDataItem) {
                if ($checkinType === 1) {
                    continue;
                } elseif (in_array($index, $canPreGetCardIndex)) {
                    $roomDataItem['startdate'] = substr($roomDataItem['startdate'], 0, 11) . $currentHourMinute;
                    $roomDataItem['enddate'] = substr($roomDataItem['enddate'], 0, 11) . $hotelCheckoutTime;
                } else {
                    $roomDataItem['startdate'] = substr($roomDataItem['startdate'], 0, 11) . $hotelCheckinTime;
                    $roomDataItem['enddate'] = substr($roomDataItem['enddate'], 0, 11) . $hotelCheckoutTime;
                }
            }
            unset($roomDataItem);
        }
        
        $userRoomId = $param['userRoom'];
        $orderUser = getArrayValueAsIndex($subOrderInfo['user'], 'userroom_id');
        $orderUserInfo = $orderUser[$userRoomId];        
        
        Vendor('phpRPC.phprpc_client');
        $client = new \PHPRPC_Client(C('MANAGE_RFCARD_URL'));
        $client->setEncryptMode(3);
        // endTime 转换成中国时间
        date_default_timezone_set('Etc/GMT-8');
        $RPCData = array(
            'flag' => 'uclbrt',
            'time' => time(),
            'communityNo'=> $hotelInfo[0]['communityno'],
            'room'=> $subOrderInfo['roominfo_name'],
            'startTime'=> strtotime($roomData[0]['startdate']),
            'endTime'=>  strtotime($roomData[0]['enddate']),
            'lost'=> empty($param['lost'])?0:1,
            'owner'=> $orderUserInfo['name'],
            'orderId'=> $orderId,
            'subOrderId' => $subOrderId, 
            'userRoomId'=> $userRoomId,
        );
        
        $result = $client->getRfcardData($RPCData);        
        if (! is_string($result)) {
            // RPC结果异常
            returnJson(500, 511);
        }
        $result = json_decode($result, true);
        if (! is_array($result)) {
            // RPC结果异常
            returnJson(500, 512);
        }
        if ($result['status']!=200) {
            // RPC结果异常
            returnJson(500, 512);
        }
        if(empty($result['data'])){
            // 未获取到卡数据
            returnJson(500, 513);
        }
    
        $HotelEntityModel = D('HotelEntity');
        $hotelInfo = $HotelEntityModel->getInfo($hotelId);
        $result['data']['isClientAvailable'] = false;
        if(! empty($hotelInfo['clientswitch']) || $result['data']['lockType'] == 5)
        {
            if(!checkClientLogin($adminId))
	        {
	            returnJson(403, 10001);
	        }
            $result['data']['isClientAvailable'] = true;
            if($result['data']['lockType'] == 2)
            {
                sendTcpClientMsg($adminId, 'issue_rfcard_t57m1_guest', array('data'=>array(
                    'serialNum' => $result['data']['serialNum'],
                    'cardData' => $result['data']['cardData'],
                    'hotelId' => $hotelId,
                    'userRoomId' => $userRoomId,
                )));
            }
            if($result['data']['lockType'] == 3)
            {
                sendTcpClientMsg($adminId, 'issue_rfcard_qrm1_guest', array('data'=>array(
                    'serialNum' => $result['data']['serialNum'],
                    'cardData' => $result['data']['cardData'],
                    'hotelId' => $hotelId,
                    'userRoomId' => $userRoomId,
                )));
            }
            if($result['data']['lockType'] == 5)
            {
                sendTcpClientMsg($adminId, 'issue_bluetooth_card', array('data'=>array(
                    'serialNum' => $result['data']['serialNum'],
                    'cardData' => $result['data']['cardData'],
                    'hotelId' => $hotelId,
                    'userRoomId' => $userRoomId,
                    'mac' => $param['mac'],
                    'readCommand' => $result['data']['readCommand'],
                )));
            }
        }
        
        returnJson(200, 200, $result['data']);
    }    
    /**
     * 查询RF卡
     * @modify paddy 2017-01-23    创建
     */
    public function reportRFData() 
    {
        $param = I('post.');
        
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'serialNum' => 'notnull,notempty,id',
            'userRoom' => 'notnull,notempty,id',
            'cardData' => 'notnull,notempty,applyDesc',   
            'oldCardData' => 'notnull,notempty,applyDesc',     
        );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (empty($validatePass)) {
            return;
        }

        // 校验酒店是否有效过期
        $hotelId = $param['hotel'];
        $hotelLogic = A('Common/Hotel', 'Logic');
        $hotelActive = $hotelLogic->checkHotelStatus($hotelId);
        if (!$hotelActive) {
            returnJson(500, 509);
            return;
        }
        $hotelActive = $hotelLogic->checkHotelActive($hotelId, true);
        if (!$hotelActive) {
            returnJson(500, 509);
            return;
        }
        
        // 获取客栈同步锁掌柜集群号
        $hotelInfo = $hotelLogic->getHotelByHotelId($hotelId);
        if (empty($hotelInfo[0]['communityno'])) {
            returnJson(500, 509);
            return;
        }
        Vendor('phpRPC.phprpc_client');
        $client = new \PHPRPC_Client(C('MANAGE_RFCARD_URL'));
        $client->setEncryptMode(3);
        $RPCData = array(
            'flag' => 'uclbrt',
            'time' => time(),
            'communityNo'=> $hotelInfo[0]['communityno'],
            'serialNum'=> $param['serialNum'],
            'cardData'=> $param['cardData'],
            'oldCardData'=> $param['oldCardData'],
        );        
        $result = $client->reportWriteResult($RPCData);
        if (! is_string($result)) {
            // RPC结果异常
            returnJson(500, 511);
        }
        $result = json_decode($result, true);
        if (! is_array($result)) {
            // RPC结果异常
            returnJson(500, 512);
        }
        if ($result['status']!=200) {
            // RPC结果异常
            returnJson(500, 512);
        }
        
        // 用户增加打印次数
        try {
            $userRoomId = $param['userRoom'];
            $orderLogic = A('Common/Order', 'Logic');
            $orderLogic->addRfCount($userRoomId);
        }
        catch (\Exception $e) {
                returnJson(500, 512);
                return;
        }
        
        returnJson(200, 200);
    }
    /**
     * 查询RF卡
     * @modify paddy 2017-01-23    创建
     */
    public function queryRFData() 
    {
        $param = I('post.');
        
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'cardData' => 'notnull,notempty,applyDesc',        
        );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (empty($validatePass)) {
            return;
        }
        // 校验酒店是否有效过期
        $hotelId = $param['hotel'];
        $hotelLogic = A('Common/Hotel', 'Logic');
        $hotelActive = $hotelLogic->checkHotelStatus($hotelId);
        if (!$hotelActive) {
            returnJson(500, 509);
            return;
        }
        $hotelActive = $hotelLogic->checkHotelActive($hotelId, true);
        if (!$hotelActive) {
            returnJson(500, 509);
            return;
        }
        
        // 获取客栈同步锁掌柜集群号
        $hotelInfo = $hotelLogic->getHotelByHotelId($hotelId);
        if (empty($hotelInfo[0]['communityno'])) {
            returnJson(500, 509);
            return;
        }

        Vendor('phpRPC.phprpc_client');
        $client = new \PHPRPC_Client(C('MANAGE_RFCARD_URL'));
        $client->setEncryptMode(3);
        $RPCData = array(
            'flag' => 'uclbrt',
            'time' => time(),
            'communityNo'=> $hotelInfo[0]['communityno'],
            'cardData'=> $param['cardData'],
        );        
        
        $result = $client->queryRfcardInfo($RPCData);

        if (! is_string($result)) {
            // RPC结果异常
            returnJson(500, 511);
        }
        //var_dump($result);
        $result = json_decode($result, true);
        if (! is_array($result)) {
            // RPC结果异常
            returnJson(500, 512);
        }
        if ($result['status']!=200) {
            // RPC结果异常
            returnJson(500, 512);
        }
        if(empty($result['data'])){
            // 未获取到卡数据
            returnJson(500, 513);
        }
        
        $userRoomModel = D('UserRoom');
        $userRoomInfo = $userRoomModel->getInfo($result['data']['userroomid']);
        if(!empty($userRoomInfo)){
            $orderUserModel = D('OrderUser');
            $orderUserInfo = $orderUserModel->getInfo($userRoomInfo[0]['orderuser_id']);
            if(!empty($orderUserInfo)){
                $result['data']['mobile'] = $orderUserInfo['mobile'];
                $result['data']['identity'] = $orderUserInfo['identity'];
            }
            $orderRoomModel = D('OrderRoom');
            $orderRoomInfo = $orderRoomModel->getInfo($userRoomInfo[0]['orderroom_id']);
            if(!empty($orderRoomInfo)){
                $result['data']['roomType'] = $orderRoomInfo[0]['roomtype_name'];
                $result['data']['room'] = $orderRoomInfo[0]['roominfo_name'];
            }
        }
        
        returnJson(200, 200, $result['data']);
    }

    /**
     * @description  获取身份证数据
     * @modify wenhui 2016-06-19
     */
    public function getOrderUserInfo() {
        $param = I('post.');

        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'orderUser' => 'notnull,notempty,id',
        );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (empty($validatePass)) {
            return;
        }

        $orderUserModel = D('OrderUser');
        $orderUserInfo = $orderUserModel->getInfo($param['orderUser']);
        if (empty($orderUserInfo)) {
            returnJson(200, 200, array(
                'idaddress' => '',
                'identity' => '',
                'idnation' => '',
                'idsex' => '',
                'name' => '',
            ));
        }
        $adminHotelModel = D('AdminHotel');
        $userId = getUserId();
        $adminHotel = $adminHotelModel->getInfoByAdminHotel($userId, $param['hotel']);
        //不是客栈创建人员，需要检查操作权限
        $isAdmin = true;
        if ($adminHotel['role'] != HOTEL_ROLE_OWNER) {
            $isAdmin = false;
        }

        // 是否屏蔽身份证信息
        $adminAuthorityLogic = A('Common/AdminAuthority', 'Logic');
        $canSeeID = $adminAuthorityLogic->check($param['hotel'], null, AUTHORITY_ID_INFO_BLOCK);
        if ($canSeeID && !$isAdmin) {
            $orderUserInfo['identity'] = !empty($orderUserInfo['identity']) ? substr($orderUserInfo['identity'], 0, 4) . '****' . substr($orderUserInfo['identity'], mb_strlen($orderUserInfo['identity'])-4) : $orderUserInfo['identity'];
            $orderUserInfo['idaddress'] = !empty($orderUserInfo['idaddress']) ? mb_substr($orderUserInfo['idaddress'], 0, 4) . '****' . mb_substr($orderUserInfo['idaddress'], mb_strlen($orderUserInfo['idaddress'])-4) : $orderUserInfo['idaddress'];
        }

        // 组装数据
        unset($orderUserInfo['id']);
        unset($orderUserInfo['orderinfo_id']);
        unset($orderUserInfo['userlogin_id']);
        unset($orderUserInfo['areacode']);
        unset($orderUserInfo['mobile']);
        unset($orderUserInfo['isdelete']);

        returnJson(200, 200, $orderUserInfo);
    }

    /**
     * @description  账户安全 发送验证码到已绑定手机
     * @modify songanwei 2016-01-08
     */
    public function sendMobile() {
        $param = I('post.');

        $validateRule = array(
            'mobile' => 'notnull,notempty,mobile',
            'areaCode' => 'notnull,notempty',
        );

        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param['mobile'], 'globalMobile',
                    array('globalMobile' => array('function', 'checkGlobalMobile,' . $param['areaCode'], '403,130,error'),
                    ));
        if (empty($validatePass)) {
            return;
        }
        // 检测60秒防刷
        $mobileSendTime = session(C('CARD_MOBILE_VCODE_TIME')) ? session(C('CARD_MOBILE_VCODE_TIME')) : 0;
        $result = time() - $mobileSendTime - 60;
        $userId = getUserId();

        //可再次发送短信验证码
        if ($result > 0) {
            $mobile = $param['mobile'];
            $areacode = $param['areaCode'];
            $mobileVcode = getRandomNumber();

            //发送短信
            if ($areacode == '86') {
                $smsUtil = new \Org\Util\Sms();
                $result = $smsUtil->sendVocode($mobile, $mobileVcode);
            } else {
                $smsUtil = new \Org\Util\yunPian();
                $result = $smsUtil->sendVcode($areacode, $mobile, $mobileVcode);
            }

            if (!$result) {
                returnJson(403, 151, 'error');
            }
            //session保存验证码
            session(C('CARD_MOBILE_VCODE'), $mobileVcode);
            //session保存验证码发送时间
            session(C('CARD_MOBILE_VCODE_TIME'), time());
            //session保存验证码有效结束时间
            session(C('CARD_MOBILE_VCODE_END_TIME'), time() + C('CARD_MOBILE_VCODE_END_TIME_EFFECTIVE'));
            returnJson(200, 200, 'success');
        } else {
            returnJson(403, 107, 'error');
        }
    }

    /**
     * @description 验证手机短信验证码
     * @modify songanwei 2016-01-08
     */
    public function verifyWithMobile() {
        $param = I('post.');
        $mobileCode = $param['vcode'];
        // 校验验证码
        $this->ajaxValidateReturn($this->validateUtil, $mobileCode, 'vcode6');

        //获取验证码结束时间
        $mobileVcodeEndTime = session(C('CARD_MOBILE_VCODE_END_TIME'));
        //获取验证码
        $mobileVcode = session(C('CARD_MOBILE_VCODE'));
        // 与session内的效验码以及过期时间进行比对
        if (($mobileVcode != $mobileCode) || ($mobileVcodeEndTime <= time())) {
            returnJson(403, 120);
        }
        session(C('CARD_MOBILE_VCODE'), null);
        session(C('CARD_MOBILE_VCODE_TIME'), null);
        session(C('CARD_MOBILE_VCODE_END_TIME'), null);
        returnJson(200, 200);
    }
    
    public function checkClient()
    {
        $param = I('post.');
        
        $hotelId = $param['hotel'];
        $adminId = getUserId();
        
        $HotelEntityModel = D('HotelEntity');
        $hotelInfo = $HotelEntityModel->getInfo($hotelId);
        
        $result['isClientAvailable'] = false;
        if(! empty($hotelInfo['clientswitch']))
        {
            if(!checkClientLogin($adminId))
            {
                returnJson(403, 10001);
            }
            $result['isClientAvailable'] = true;
            $cmd = 'issue_rfcard_t57m1_guest';
            if($param['deviceType'] == 3)
            {
                $cmd = 'issue_rfcard_qrm1_guest';
            }
            sendTcpClientMsg($adminId, $cmd, array('data'=>array(
                'cardData' => $result['data']['cardData'],
            )));
        }
        
        returnJson(200, 200, $result);
    }

    /**
     * 退房查房接口
     * @modify wenhui 2018-02-28    创建
     */
    public function orderRoomCheck() {
        $param = I('post.');
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
            'order' => 'notnull,notempty,id',
            'suborder' => 'notnull,notempty,concatId',
        );

        $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);

        $hotelId = $param['hotel'];
        $orderId = $param['order'];
        $subOrderIds = explode(',', $param['suborder']);

        $orderLogic = A('Common/Order', 'Logic');
        try {
            $orderLogic->addOrderRoomCheck($hotelId, $orderId, $subOrderIds);
        } catch (\Exception $e) {
            returnJson($e->getMessage());
            return;
        }

        returnJson(200, 200);
        return;
    }
    
    public function getBthDeviceList()
    {
        $param = I('post.');
        
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
        );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (empty($validatePass)) {
            return;
        }
        // 校验酒店是否有效过期
        $hotelId = $param['hotel'];
        $hotelLogic = A('Common/Hotel', 'Logic');
        $hotelActive = $hotelLogic->checkHotelStatus($hotelId);
        if (!$hotelActive) {
            returnJson(500, 10100);
            return;
        }
        $hotelActive = $hotelLogic->checkHotelActive($hotelId, true);
        if (!$hotelActive) {
            returnJson(500, 10100);
            return;
        }
        
        // 获取客栈同步锁掌柜集群号
        $hotelInfo = $hotelLogic->getHotelByHotelId($hotelId);
        if (empty($hotelInfo[0]['communityno'])) {
            returnJson(500, 10100);
            return;
        }
        
        Vendor('phpRPC.phprpc_client');
        $client = new \PHPRPC_Client(C('MANAGE_RFCARD_URL'));
        $client->setEncryptMode(3);
        $RPCData = array(
            'flag' => 'uclbrt',
            'time' => time(),
            'communityNo'=> $hotelInfo[0]['communityno'],
        );
        
        $result = $client->getBthDeviceList($RPCData);
        
        if (! is_string($result)) {
            // RPC结果异常
            returnJson(500, 10101);
        }
        //var_dump($result);
        $result = json_decode($result, true);
        if (! is_array($result)) {
            // RPC结果异常
            returnJson(500, 10101);
        }
        if ($result['status']!=200) {
            // RPC结果异常
            returnJson(500, 10101);
        }
        if(empty($result['data'])){
            // 未获取到卡数据
            returnJson(500, 10101);
        }
        returnJson(200, 200, $result['data']);
    }
    
    public function reportCancelCard()
    {
        $param = I('post.');
        
        $adminId = getUserId();
        
        $validateRule = array(
            'hotel' => 'notnull,notempty,id',
        );
        $validatePass = $this->ajaxValidateReturn($this->validateUtil, $param, $validateRule);
        if (empty($validatePass)) {
            return;
        }
        // 校验酒店是否有效过期
        $hotelId = $param['hotel'];
        $hotelLogic = A('Common/Hotel', 'Logic');
        $hotelActive = $hotelLogic->checkHotelStatus($hotelId);
        if (!$hotelActive) {
            returnJson(500, 10100);
            return;
        }
        $hotelActive = $hotelLogic->checkHotelActive($hotelId, true);
        if (!$hotelActive) {
            returnJson(500, 10100);
            return;
        }
        
        // 获取客栈同步锁掌柜集群号
        $hotelInfo = $hotelLogic->getHotelByHotelId($hotelId);
        if (empty($hotelInfo[0]['communityno'])) {
            returnJson(500, 10100);
            return;
        }
        
        if(!empty($param['isClientAvailable']) || $param['cardType']==4)
        {
            if(!checkClientLogin($adminId))
            {
                returnJson(403, 10001);
            }

            Vendor('phpRPC.phprpc_client');
            $client = new \PHPRPC_Client(C('MANAGE_RFCARD_URL'));
            $client->setEncryptMode(3);
            $RPCData = array(
                'flag' => 'uclbrt',
                'time' => time(),
                'serialNum'=> $param['serialNum'],
                'communityNo'=> $hotelInfo[0]['communityno'],
            );
            
            $result = $client->reportCancelCard($RPCData);
            
            if (! is_string($result)) {
                // RPC结果异常
                returnJson(500, 511);
            }
            $result = json_decode($result, true);
            if (! is_array($result)) {
                // RPC结果异常
                returnJson(500, 512);
            }
            if ($result['status']!=200) {
                // RPC结果异常
                returnJson(500, 512);
            }
            
            switch ($param['cardType'])
            {
                case "4":
                    sendTcpClientMsg($adminId, 'clear_btcard', array(
                        'mac' => $param['mac'],
                        'deviceCommand' => $param['deviceCommand'],
                    ));
                    break;
                case "3":
                    sendTcpClientMsg($adminId, 'clear_rfcard_qrm1', null);
                    break;
                default:
                    sendTcpClientMsg($adminId, 'clear_rfcard_t57m1', null);
                    break;
            }
        }
        returnJson(200, 200, $result);
    }
}
